QCAD::ResponseFieldIntegral<EvalT, Traits>:: ResponseFieldIntegral(Teuchos::ParameterList& p, const Teuchos::RCP<Albany::Layouts>& dl) : coordVec("Coord Vec", dl->qp_vector), weights("Weights", dl->qp_scalar) { //! get and validate Response parameter list Teuchos::ParameterList* plist = p.get<Teuchos::ParameterList*>("Parameter List"); Teuchos::RCP<const Teuchos::ParameterList> reflist = this->getValidResponseParameters(); plist->validateParameters(*reflist,0); //! parameters passed down from problem Teuchos::RCP<Teuchos::ParameterList> paramsFromProblem = p.get< Teuchos::RCP<Teuchos::ParameterList> >("Parameters From Problem"); if(paramsFromProblem != Teuchos::null) { // Material database materialDB = paramsFromProblem->get< Teuchos::RCP<QCAD::MaterialDatabase> >("MaterialDB"); // Length unit in meters length_unit_in_m = paramsFromProblem->get<double>("Length unit in m"); } else { materialDB = Teuchos::null; length_unit_in_m = 1.0e-6; //default length unit = microns (backward compat) } //! number of quad points per cell Teuchos::RCP<PHX::DataLayout> scalar_dl = dl->qp_scalar; numQPs = scalar_dl->dimension(1); //! obtain number of dimensions Teuchos::RCP<PHX::DataLayout> vector_dl = dl->qp_vector; std::vector<PHX::DataLayout::size_type> dims; vector_dl->dimensions(dims); numDims = dims[2]; //! Initialize Region opRegion = Teuchos::rcp( new QCAD::MeshRegion<EvalT, Traits>("Coord Vec","Weights",*plist,materialDB,dl) ); //! User-specified parameters std::string fieldName; fieldName = plist->get<std::string>("Field Name",""); if(fieldName.length() > 0) { fieldNames.push_back(fieldName); conjugateFieldFlag.push_back(plist->get<bool>("Conjugate Field",false)); fieldName = plist->get<std::string>("Field Name Im",""); fieldNames_Imag.push_back(fieldName); if(fieldName.length() > 0) fieldIsComplex.push_back(true); else fieldIsComplex.push_back(false); } for(int i=1; i < QCAD::MAX_FIELDNAMES_IN_INTEGRAL; i++) { fieldName = plist->get<std::string>(Albany::strint("Field Name",i),""); if(fieldName.length() > 0) { fieldNames.push_back(fieldName); conjugateFieldFlag.push_back(plist->get<bool>(Albany::strint("Conjugate Field",i),false)); fieldName = plist->get<std::string>(Albany::strint("Field Name Im",i),""); fieldNames_Imag.push_back(fieldName); if(fieldName.length() > 0) fieldIsComplex.push_back(true); else fieldIsComplex.push_back(false); } else break; } bReturnImagPart = plist->get<bool>("Return Imaginary Part",false); std::string integrandLinLengthUnit; // linear length unit of integrand (e.g. "cm" for integrand in cm^-3) integrandLinLengthUnit = plist->get<std::string>("Integrand Length Unit","cm"); bPositiveOnly = plist->get<bool>("Positive Return Only",false); //! compute scaling factor based on number of dimensions and units double integrand_length_unit_in_m; if( integrandLinLengthUnit == "m" ) integrand_length_unit_in_m = 1.0; else if( integrandLinLengthUnit == "cm" ) integrand_length_unit_in_m = 1e-2; else if( integrandLinLengthUnit == "um" ) integrand_length_unit_in_m = 1e-6; else if( integrandLinLengthUnit == "nm" ) integrand_length_unit_in_m = 1e-9; else if( integrandLinLengthUnit == "mesh" ) integrand_length_unit_in_m = length_unit_in_m; else integrand_length_unit_in_m = length_unit_in_m; // assume same unit as mesh (e.g. if unit string is blank) double X0 = length_unit_in_m / integrand_length_unit_in_m; // length scaling to get to integrand's lenght unit if (numDims == 1) scaling = X0; else if (numDims == 2) scaling = X0*X0; else if (numDims == 3) scaling = X0*X0*X0; else TEUCHOS_TEST_FOR_EXCEPTION (true, Teuchos::Exceptions::InvalidParameter, std::endl << "Error! Invalid number of dimensions: " << numDims << std::endl); //! add dependent fields (all fields assumed scalar qp) std::vector<std::string>::const_iterator it; //for(it = fieldNames.begin(); it != fieldNames.end(); ++it) { for(std::size_t i=0; i<fieldNames.size(); i++) { PHX::MDField<ScalarT,Cell,QuadPoint> f(fieldNames[i], scalar_dl); fields.push_back(f); this->addDependentField(f); PHX::MDField<ScalarT,Cell,QuadPoint> fi(fieldNames_Imag[i], scalar_dl); fields_Imag.push_back(fi); if(fieldIsComplex[i]) this->addDependentField(fi); } this->addDependentField(coordVec); this->addDependentField(weights); opRegion->addDependentFields(this); //TODO: make name unique? Is this needed for anything? this->setName(fieldName+" Response Field Integral"+PHX::TypeString<EvalT>::value); // Setup scatter evaluator p.set("Stand-alone Evaluator", false); std::string local_response_name = fieldName + " Local Response Field Integral"; std::string global_response_name = fieldName + " Global Response Field Integral"; PHX::Tag<ScalarT> local_response_tag(local_response_name, dl->cell_scalar); PHX::Tag<ScalarT> global_response_tag(global_response_name, dl->workset_scalar); p.set("Local Response Field Tag", local_response_tag); p.set("Global Response Field Tag", global_response_tag); PHAL::SeparableScatterScalarResponse<EvalT,Traits>::setup(p,dl); }
PHAL::ResponseFieldIntegral<EvalT, Traits>:: ResponseFieldIntegral(Teuchos::ParameterList& p, const Teuchos::RCP<Albany::Layouts>& dl) : coordVec("Coord Vec", dl->qp_gradient), weights("Weights", dl->qp_scalar) { // get and validate Response parameter list Teuchos::ParameterList* plist = p.get<Teuchos::ParameterList*>("Parameter List"); Teuchos::RCP<const Teuchos::ParameterList> reflist = this->getValidResponseParameters(); plist->validateParameters(*reflist,0); // Get field type and corresponding layouts std::string field_name = plist->get<std::string>("Field Name"); std::string fieldType = plist->get<std::string>("Field Type", "Scalar"); if (plist->isType< Teuchos::Array<int> >("Field Components")) field_components = plist->get< Teuchos::Array<int> >("Field Components"); Teuchos::RCP<PHX::DataLayout> field_layout; Teuchos::RCP<PHX::DataLayout> local_response_layout; Teuchos::RCP<PHX::DataLayout> global_response_layout; if (fieldType == "Scalar") { field_layout = dl->qp_scalar; local_response_layout = dl->cell_scalar; global_response_layout = dl->workset_scalar; } else if (fieldType == "Vector") { field_layout = dl->qp_vector; if (field_components.size() == 0) { local_response_layout = dl->cell_vector; global_response_layout = dl->workset_vector; } else { int worksetSize = dl->cell_scalar->dimension(0); local_response_layout = Teuchos::rcp(new PHX::MDALayout<Cell,Dim>(worksetSize, field_components.size())); global_response_layout = Teuchos::rcp(new PHX::MDALayout<Dim>(field_components.size())); } } else if (fieldType == "Tensor") { TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "local_ and global_response must have rank 2. However, this code path " "makes them rank 3. Needs to be fixed."); field_layout = dl->qp_tensor; local_response_layout = dl->cell_tensor; global_response_layout = dl->workset_tensor; } else { TEUCHOS_TEST_FOR_EXCEPTION( true, Teuchos::Exceptions::InvalidParameter, "Invalid field type " << fieldType << ". Support values are " << "Scalar, Vector, and Tensor." << std::endl); } field = PHX::MDField<ScalarT>(field_name, field_layout); field_layout->dimensions(field_dims); field_rank = field_layout->rank(); if (field_components.size() == 0) { int num_components = field_dims[field_rank-1]; field_components.resize(num_components); for (int i=0; i<num_components; i++) field_components[i] = i; } // coordinate dimensions std::vector<PHX::DataLayout::size_type> coord_dims; dl->qp_vector->dimensions(coord_dims); numQPs = coord_dims[1]; numDims = coord_dims[2]; // User-specified parameters std::string ebNameStr = plist->get<std::string>("Element Block Name",""); if(ebNameStr.length() > 0) split(ebNameStr,',',ebNames); limitX = limitY = limitZ = false; if( plist->isParameter("x min") && plist->isParameter("x max") ) { limitX = true; TEUCHOS_TEST_FOR_EXCEPT(numDims <= 0); xmin = plist->get<double>("x min"); xmax = plist->get<double>("x max"); } if( plist->isParameter("y min") && plist->isParameter("y max") ) { limitY = true; TEUCHOS_TEST_FOR_EXCEPT(numDims <= 1); ymin = plist->get<double>("y min"); ymax = plist->get<double>("y max"); } if( plist->isParameter("z min") && plist->isParameter("z max") ) { limitZ = true; TEUCHOS_TEST_FOR_EXCEPT(numDims <= 2); zmin = plist->get<double>("z min"); zmax = plist->get<double>("z max"); } // length scaling double X0 = plist->get<double>("Length Scaling", 1.0); if (numDims == 1) scaling = X0; else if (numDims == 2) scaling = X0*X0; else if (numDims == 3) scaling = X0*X0*X0; else TEUCHOS_TEST_FOR_EXCEPTION( true, Teuchos::Exceptions::InvalidParameter, std::endl << "Error! Invalid number of dimensions: " << numDims << std::endl); // add dependent fields this->addDependentField(field); this->addDependentField(coordVec); this->addDependentField(weights); this->setName(field_name+" Response Field Integral"+PHX::typeAsString<EvalT>()); // Setup scatter evaluator p.set("Stand-alone Evaluator", false); std::string local_response_name = field_name + " Local Response Field Integral"; std::string global_response_name = field_name + " Global Response Field Integral"; PHX::Tag<ScalarT> local_response_tag(local_response_name, local_response_layout); PHX::Tag<ScalarT> global_response_tag(global_response_name, global_response_layout); p.set("Local Response Field Tag", local_response_tag); p.set("Global Response Field Tag", global_response_tag); PHAL::SeparableScatterScalarResponse<EvalT,Traits>::setup(p,dl); }