void SaveStateField<PHAL::AlbanyTraits::Residual, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  // Get shards Array (from STK) for this state
  // Need to check if we can just copy full size -- can assume same ordering?
    Albany::StateArray::const_iterator it;
    it = workset.stateArrayPtr->find(stateName);

    TEUCHOS_TEST_FOR_EXCEPTION((it == workset.stateArrayPtr->end()), std::logic_error,
           std::endl << "Error: cannot locate " << stateName << " in PHAL_SaveStateField_Def" << std::endl);

    Albany::MDArray sta = it->second;
    std::vector<PHX::DataLayout::size_type> dims;
    sta.dimensions(dims);
    int size = dims.size();

    switch (size) {
    case 1:
      for (int cell = 0; cell < dims[0]; ++cell)
      sta(cell) = field(cell);
      break;
    case 2:
      for (int cell = 0; cell < dims[0]; ++cell)
	for (int qp = 0; qp < dims[1]; ++qp)
	  sta(cell, qp) = field(cell,qp);;
      break;
    case 3:
      for (int cell = 0; cell < dims[0]; ++cell)
	for (int qp = 0; qp < dims[1]; ++qp)
	  for (int i = 0; i < dims[2]; ++i)
	    sta(cell, qp, i) = field(cell,qp,i);
      break;
    case 4:
      for (int cell = 0; cell < dims[0]; ++cell)
	for (int qp = 0; qp < dims[1]; ++qp)
	  for (int i = 0; i < dims[2]; ++i)
	    for (int j = 0; j < dims[3]; ++j)
	      sta(cell, qp, i, j) = field(cell,qp,i,j);
      break;
    case 5:
      for (int cell = 0; cell < dims[0]; ++cell)
	for (int qp = 0; qp < dims[1]; ++qp)
	  for (int i = 0; i < dims[2]; ++i)
	    for (int j = 0; j < dims[3]; ++j)
	      for (int k = 0; k < dims[4]; ++k)
	      sta(cell, qp, i, j, k) = field(cell,qp,i,j,k);
      break;
    default:
      TEUCHOS_TEST_FOR_EXCEPT_MSG(size<1||size>5,
                          "Unexpected Array dimensions in SaveStateField: " << size);
    }

}
void Adapt::ElementSizeField<PHAL::AlbanyTraits::Residual, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  double value;

  if( this->outputCellAverage ) { // nominal radius

    // Get shards Array (from STK) for this workset
    Albany::MDArray data = (*workset.stateArrayPtr)[this->className + "_Cell"];
    std::vector<int> dims;
    data.dimensions(dims);
    int size = dims.size();


    for (std::size_t cell = 0; cell < workset.numCells; ++cell) {
          this->getCellRadius(cell, value);
//          data(cell, (std::size_t)0) = ADValue(value);
          data(cell, (std::size_t)0) = value;
    }
  }

  if( this->outputQPData ) { // x_\xi \cdot x_\xi, x_\eta \cdot x_\eta, x_\zeta \cdot x_\zeta

    // Get shards Array (from STK) for this workset
    Albany::MDArray data = (*workset.stateArrayPtr)[this->className + "_QP"];
    std::vector<int> dims;
    data.dimensions(dims);
    int size = dims.size();


    for (std::size_t cell = 0; cell < workset.numCells; ++cell) {
          this->getCellRadius(cell, value);
//          data(cell, (std::size_t)0) = ADValue(value);
          data(cell, (std::size_t)0) = value;
    }
/*
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t qp=0; qp < numQPs; ++qp) {
        for (std::size_t i=0; i < numDims; ++i) { // loop over \xi, \eta, \zeta
          data(cell, qp, i) = 0.0;
          for (std::size_t j=0; j < numDims; ++j) {
            data(cell, qp, i) += coordVec(cell, qp, j) * wGradBF(cell, node, qp, j);
            for (std::size_t alpha=0; alpha < numDims; ++alpha) {
              Gc(cell,qp,i,j) += jacobian_inv(cell,qp,alpha,i)*jacobian_inv(cell,qp,alpha,j);
            }
          }
        }
      }
    }
*/

  }

  if( this->outputNodeData ) { // nominal radius, store as nodal data that will be scattered and summed

    // Get the node data block container
    Teuchos::RCP<Adapt::NodalDataBlock> node_data =
      this->pStateMgr->getStateInfoStruct()->getNodalDataBase()->getNodalDataBlock();
    Teuchos::ArrayRCP<ST> data = node_data->getLocalNodeView();
    Teuchos::ArrayRCP<Teuchos::ArrayRCP<GO> >  wsElNodeID = workset.wsElNodeID;
    Teuchos::RCP<const Tpetra_BlockMap> local_node_map = node_data->getLocalMap();

    int l_nV = this->numVertices;
    int l_nD = this->numDims;

    int  node_var_offset;
    int  node_var_ndofs;
    int  node_weight_offset;
    int  node_weight_ndofs;
    node_data->getNDofsAndOffset(this->className + "_Node", node_var_offset, node_var_ndofs);
    node_data->getNDofsAndOffset(this->className + "_NodeWgt", node_weight_offset, node_weight_ndofs);

    for (int cell = 0; cell < workset.numCells; ++cell) { // loop over all elements in workset

      std::vector<double> maxCoord(3,-1e10);
      std::vector<double> minCoord(3,+1e10);

      // Get element width in x, y, z
      for (int v=0; v < l_nV; ++v) { // loop over all the "corners" of each element
        for (int k=0; k < l_nD; ++k) { // loop over each dimension of the problem
          if(maxCoord[k] < this->coordVec_vertices(cell,v,k)) maxCoord[k] = this->coordVec_vertices(cell,v,k);
          if(minCoord[k] > this->coordVec_vertices(cell,v,k)) minCoord[k] = this->coordVec_vertices(cell,v,k);
        }
      }

      if(this->isAnisotropic) //An-isotropic
        // Note: code assumes blocksize of blockmap is numDims + 1 - the last entry accumulates the weight
        for (int node = 0; node < l_nV; ++node) { // loop over all the "corners" of each element

          GO global_block_id = wsElNodeID[cell][node]; // get the global id of this node
          LO local_block_id = local_node_map->getLocalBlockID(global_block_id);

          // skip the node if it is not owned by me
          if(local_block_id == Teuchos::OrdinalTraits<LO>::invalid()) continue;
          LO first_local_dof = local_node_map->getFirstLocalPointInLocalBlock(local_block_id);

          // accumulate 1/2 of the element width in each dimension - into each element corner
          for (int k=0; k < node_var_ndofs; ++k)
//            data[global_node][k] += ADValue(maxCoord[k] - minCoord[k]) / 2.0;
            data[first_local_dof + node_var_offset + k] += (maxCoord[k] - minCoord[k]) / 2.0;

          // save the weight (denominator)
          data[first_local_dof + node_weight_offset] += 1.0;

      } // end anisotropic size field

      else // isotropic size field
        // Note: code assumes blocksize of blockmap is 1 + 1 = 2 - the last entry accumulates the weight
        for (int node = 0; node < l_nV; ++node) { // loop over all the "corners" of each element

          GO global_block_id = wsElNodeID[cell][node]; // get the global id of this node
          LO local_block_id = local_node_map->getLocalBlockID(global_block_id);

          // skip the node if it is not owned by me
          if(local_block_id == Teuchos::OrdinalTraits<LO>::invalid()) continue;
          LO first_local_dof = local_node_map->getFirstLocalPointInLocalBlock(local_block_id);

          // save element radius, just a scalar
          for (int k=0; k < l_nD; ++k) {
//            data[global_node][k] += ADValue(maxCoord[k] - minCoord[k]) / 2.0;
            data[first_local_dof + node_var_offset] += (maxCoord[k] - minCoord[k]) / 2.0;
            // save the weight (denominator)
            data[first_local_dof + node_weight_offset] += 1.0;

          }


          // the above calculates the average of the element width, depth, and height when
          // divided by the accumulated weights

      } // end isotropic size field
    } // end cell loop
  } // end node data if

}
Beispiel #3
0
void QCAD::ResponseSaveField<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  using Albany::ADValue;

  const std::size_t iX=0; //index for x coordinate
  const std::size_t iY=1; //index for y coordinate
  const std::size_t iZ=2; //index for z coordinate

  //Don't do anything if this response is just used to allocate 
  // and hold a block of memory (the state)
  if(memoryHolderOnly) return;

  // Get shards Array (from STK) for this state
  // Need to check if we can just copy full size -- can assume same ordering?
  Albany::MDArray sta = (*workset.stateArrayPtr)[stateName];
  std::vector<PHX::DataLayout::size_type> dims;
  sta.dimensions(dims);
  int size = dims.size();

  if(!isVectorField) {
    switch (size) {  //Note: size should always == 2 now: qp_scalar type or cell_sclar state registered
    case 2:     
      for (std::size_t cell = 0; cell < workset.numCells; ++cell) {
        if( outputCellAverage ) {
          double integral = 0, vol = 0;
	  for (std::size_t qp = 0; qp < numQPs; ++qp) {
	    integral += ADValue(field(cell,qp)) * ADValue(weights(cell,qp));
            vol += ADValue(weights(cell, qp));
          }
          sta(cell,(std::size_t)0) = integral / vol;
        }
        else {
	  for (std::size_t qp = 0; qp < numQPs; ++qp)
	    sta(cell, qp) = ADValue(field(cell,qp));
        }
      }
      break;
      /*case 3:     
      for (int cell = 0; cell < dims[0]; ++cell)
	for (int qp = 0; qp < dims[1]; ++qp)
	  for (int i = 0; i < dims[2]; ++i)
	    sta(cell, qp, i) = field(cell,qp,i);
      break;
    case 4:     
      for (int cell = 0; cell < dims[0]; ++cell)
	for (int qp = 0; qp < dims[1]; ++qp)
	  for (int i = 0; i < dims[2]; ++i)
	    for (int j = 0; j < dims[3]; ++j)
	      sta(cell, qp, i, j) = field(cell,qp,i,j);
      break;
      */
    default:
      TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
       "Unexpected dimensions in SaveField response Evaluator: " << size);
    }
  }
  else {
    ScalarT t;
    switch (size) {
    case 2:     
      for (std::size_t cell = 0; cell < workset.numCells; ++cell) {

	ScalarT stateValue = 0.0;
	double vol = 0.0;
	if( outputCellAverage ) sta(cell,(std::size_t)0) = 0.0;

	for (std::size_t qp = 0; qp < numQPs; ++qp) {
	  t = 0.0;

	  if(vectorOp == "magnitude") {
	    for (std::size_t i = 0; i < numDims; ++i)
	      t += field(cell,qp,i)*field(cell,qp,i);
	    stateValue = sqrt(t);
	  }
	  else if(vectorOp == "xyMagnitude") {
	    if(numDims > iX) t += field(cell,qp,iX)*field(cell,qp,iX);
	    if(numDims > iY) t += field(cell,qp,iY)*field(cell,qp,iY);
	    stateValue = sqrt(t);
	  }
	  else if(vectorOp == "xzMagnitude") {
	    if(numDims > iX) t += field(cell,qp,iX)*field(cell,qp,iX);
	    if(numDims > iZ) t += field(cell,qp,iZ)*field(cell,qp,iZ);
	    stateValue = sqrt(t);
	  }
	  else if(vectorOp == "yzMagnitude") {
	    if(numDims > iY) t += field(cell,qp,iY)*field(cell,qp,iY);
	    if(numDims > iZ) t += field(cell,qp,iZ)*field(cell,qp,iZ);
	    stateValue = sqrt(t);
	  }

	  else if(vectorOp == "magnitude2") {
	    for (std::size_t i = 0; i < numDims; ++i)
	      t += field(cell,qp,i)*field(cell,qp,i);
	    stateValue = t;
	  }
	  else if(vectorOp == "xyMagnitude2") {
	    if(numDims > iX) t += field(cell,qp,iX)*field(cell,qp,iX);
	    if(numDims > iY) t += field(cell,qp,iY)*field(cell,qp,iY);
	    stateValue = t;
	  }
	  else if(vectorOp == "xzMagnitude2") {
	    if(numDims > iX) t += field(cell,qp,iX)*field(cell,qp,iX);
	    if(numDims > iZ) t += field(cell,qp,iZ)*field(cell,qp,iZ);
	    stateValue = t;
	  }
	  else if(vectorOp == "yzMagnitude2") {
	    if(numDims > iY) t += field(cell,qp,iY)*field(cell,qp,iY);
	    if(numDims > iZ) t += field(cell,qp,iZ)*field(cell,qp,iZ);
	    stateValue = t;
	  }

	  else if(vectorOp == "xCoord") {
	    if(numDims > iX) stateValue = field(cell,qp,iX);
	  }
	  else if(vectorOp == "yCoord") {
	    if(numDims > iY) stateValue = field(cell,qp,iY);
	  }
	  else if(vectorOp == "zCoord") {
	    if(numDims > iZ) stateValue = field(cell,qp,iZ);
	  }
	  else {
	    TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
	       "Unknown vector operation: " << vectorOp);
	  }

	  if( outputCellAverage ) {
	    sta(cell, (std::size_t)0) += ADValue(stateValue) * ADValue(weights(cell,qp));
	    vol += ADValue(weights(cell,qp));
	  }
	  else sta(cell, qp) = ADValue(stateValue);
	}

	if( outputCellAverage ) sta(cell,(std::size_t)0) /= vol;
      }
      break;
    default:
      TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
       "Unexpected dimensions in SaveField response Evaluator: " << size);
    }
  }
}