Beispiel #1
0
// computes riesz representation over a single element - map is from int (testID) to FieldContainer of values (sized cellIndex, numPoints)
void RieszRep::computeRepresentationValues(FieldContainer<double> &values, int testID, IntrepidExtendedTypes::EOperatorExtended op, BasisCachePtr basisCache){

  if (_repsNotComputed){
    cout << "Computing riesz rep dofs" << endl;
    computeRieszRep();
  }

  int spaceDim = _mesh->getTopology()->getSpaceDim();
  int numCells = values.dimension(0);
  int numPoints = values.dimension(1);
  vector<GlobalIndexType> cellIDs = basisCache->cellIDs();

  // all elems coming in should be of same type
  ElementPtr elem = _mesh->getElement(cellIDs[0]);
  ElementTypePtr elemTypePtr = elem->elementType();   
  DofOrderingPtr testOrderingPtr = elemTypePtr->testOrderPtr;
  CellTopoPtrLegacy cellTopoPtr = elemTypePtr->cellTopoPtr;
  int numTestDofsForVarID = testOrderingPtr->getBasisCardinality(testID, 0);
  BasisPtr testBasis = testOrderingPtr->getBasis(testID);
  
  bool testBasisIsVolumeBasis = (spaceDim == testBasis->domainTopology()->getDimension());  
  bool useCubPointsSideRefCell = testBasisIsVolumeBasis && basisCache->isSideCache();
  
  Teuchos::RCP< const FieldContainer<double> > transformedBasisValues = basisCache->getTransformedValues(testBasis,op,useCubPointsSideRefCell);
  
  int rank = values.rank() - 2; // if values are shaped as (C,P), scalar...
  if (rank > 1) {
    cout << "ranks greater than 1 not presently supported...\n";
    TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "ranks greater than 1 not presently supported...");
  }
  
//  Camellia::print("cellIDs",cellIDs);
  
  values.initialize(0.0);
  for (int cellIndex = 0;cellIndex<numCells;cellIndex++){
    int cellID = cellIDs[cellIndex];
    for (int j = 0;j<numTestDofsForVarID;j++) {
      int dofIndex = testOrderingPtr->getDofIndex(testID, j);
      for (int i = 0;i<numPoints;i++) {
        if (rank==0) {
          double basisValue = (*transformedBasisValues)(cellIndex,j,i);
          values(cellIndex,i) += basisValue*_rieszRepDofsGlobal[cellID](dofIndex);
        } else {
          for (int d = 0; d<spaceDim; d++) {
            double basisValue = (*transformedBasisValues)(cellIndex,j,i,d);
            values(cellIndex,i,d) += basisValue*_rieszRepDofsGlobal[cellID](dofIndex);
          }
        }
      }
    }
  }
//  TestSuite::serializeOutput("rep values", values);
}
Beispiel #2
0
double RieszRep::computeAlternativeNormSqOnCell(IPPtr ip, ElementPtr elem){
  GlobalIndexType cellID = elem->cellID();
  Teuchos::RCP<DofOrdering> testOrdering= elem->elementType()->testOrderPtr;
  bool testVsTest = true;
  Teuchos::RCP<BasisCache> basisCache =   BasisCache::basisCacheForCell(_mesh, cellID, testVsTest,1);

  int numDofs = testOrdering->totalDofs();
  FieldContainer<double> ipMat(1,numDofs,numDofs);
  ip->computeInnerProductMatrix(ipMat,testOrdering,basisCache);

  double sum = 0.0;
  for (int i = 0;i<numDofs;i++){
    for (int j = 0;j<numDofs;j++){
      sum += _rieszRepDofsGlobal[cellID](i)*_rieszRepDofsGlobal[cellID](j)*ipMat(0,i,j);
    }
  }
  
  return sum;
}
Beispiel #3
0
map< int, vector<DofInfo> > constructGlobalDofToLocalDofInfoMap(MeshPtr mesh)
{
  // go through the mesh as a whole, and collect info for each dof
  map< int, vector<DofInfo> > infoMap;
  DofInfo info;
  set<GlobalIndexType> activeCellIDs = mesh->getActiveCellIDsGlobal();
  for (set<GlobalIndexType>::iterator cellIt = activeCellIDs.begin(); cellIt != activeCellIDs.end(); cellIt++)
  {
    GlobalIndexType cellID = *cellIt;
    info.cellID = cellID;
    ElementPtr element = mesh->getElement(cellID);
    DofOrderingPtr trialOrder = element->elementType()->trialOrderPtr;
    set<int> trialIDs = trialOrder->getVarIDs();
    info.totalDofs = trialOrder->totalDofs();
    for (set<int>::iterator trialIt=trialIDs.begin(); trialIt != trialIDs.end(); trialIt++)
    {
      info.trialID = *trialIt;
      const vector<int>* sidesForVar = &trialOrder->getSidesForVarID(info.trialID);
      for (vector<int>::const_iterator sideIt = sidesForVar->begin(); sideIt != sidesForVar->end(); sideIt++)
      {
        int sideIndex = *sideIt;
        info.sideIndex = sideIndex;
        info.basisCardinality = trialOrder->getBasisCardinality(info.trialID, info.sideIndex);
        for (int basisOrdinal=0; basisOrdinal < info.basisCardinality; basisOrdinal++)
        {
          info.basisOrdinal = basisOrdinal;
          info.localDofIndex = trialOrder->getDofIndex(info.trialID, info.basisOrdinal, info.sideIndex);
          pair<int, int> localDofIndexKey = make_pair(info.cellID, info.localDofIndex);
          int globalDofIndex = mesh->getLocalToGlobalMap().find(localDofIndexKey)->second;
//          cout << "(" << info.cellID << "," << info.localDofIndex << ") --> " << globalDofIndex << endl;
          infoMap[globalDofIndex].push_back(info);
        }
      }
    }
  }
  return infoMap;
}
Beispiel #4
0
bool ScratchPadTests::testGalerkinOrthogonality()
{

  double tol = 1e-11;
  bool success = true;

  ////////////////////   DECLARE VARIABLES   ///////////////////////
  // define test variables
  VarFactoryPtr varFactory = VarFactory::varFactory();
  VarPtr v = varFactory->testVar("v", HGRAD);

  vector<double> beta;
  beta.push_back(1.0);
  beta.push_back(1.0);

  ////////////////////   DEFINE INNER PRODUCT(S)   ///////////////////////

  // robust test norm
  IPPtr ip = Teuchos::rcp(new IP);
  ip->addTerm(v);
  ip->addTerm(beta*v->grad());

  // define trial variables
  VarPtr beta_n_u = varFactory->fluxVar("\\widehat{\\beta \\cdot n }");
  VarPtr u = varFactory->fieldVar("u");

  ////////////////////   BUILD MESH   ///////////////////////

  BFPtr convectionBF = Teuchos::rcp( new BF(varFactory) );

  FunctionPtr n = Function::normal();
  // v terms:
  convectionBF->addTerm( -u, beta * v->grad() );
  convectionBF->addTerm( beta_n_u, v);

  // define nodes for mesh
  int order = 2;
  int H1Order = order+1;
  int pToAdd = 1;

  // create a pointer to a new mesh:
  Teuchos::RCP<Mesh> mesh = MeshUtilities::buildUnitQuadMesh(4, convectionBF, H1Order, H1Order+pToAdd);

  ////////////////////   SOLVE   ///////////////////////

  RHSPtr rhs = RHS::rhs();
  BCPtr bc = BC::bc();
  SpatialFilterPtr inflowBoundary = Teuchos::rcp( new InflowSquareBoundary );
  SpatialFilterPtr outflowBoundary = Teuchos::rcp( new NegatedSpatialFilter(inflowBoundary) );

  FunctionPtr uIn;
  uIn = Teuchos::rcp(new Uinflow); // uses a discontinuous piecewise-constant basis function on left and bottom sides of square
  bc->addDirichlet(beta_n_u, inflowBoundary, beta*n*uIn);

  Teuchos::RCP<Solution> solution;
  solution = Teuchos::rcp( new Solution(mesh, bc, rhs, ip) );
  solution->solve(false);
  FunctionPtr uFxn = Function::solution(u, solution);
  FunctionPtr fnhatFxn = Function::solution(beta_n_u,solution);

  // make residual for riesz representation function
  LinearTermPtr residual = Teuchos::rcp(new LinearTerm);// residual
  FunctionPtr parity = Function::sideParity();
  residual->addTerm(-fnhatFxn*v + (beta*uFxn)*v->grad());
  Teuchos::RCP<RieszRep> riesz = Teuchos::rcp(new RieszRep(mesh, ip, residual));
  riesz->computeRieszRep();
  map<int,FunctionPtr> err_rep_map;
  err_rep_map[v->ID()] = RieszRep::repFunction(v,riesz);

  ////////////////////   GET BOUNDARY CONDITION DATA    ///////////////////////

  FieldContainer<GlobalIndexType> bcGlobalIndices;
  FieldContainer<double> bcGlobalValues;
  mesh->boundary().bcsToImpose(bcGlobalIndices,bcGlobalValues,*(solution->bc()), NULL);
  set<int> bcInds;
  for (int i=0; i<bcGlobalIndices.dimension(0); i++)
  {
    bcInds.insert(bcGlobalIndices(i));
  }

  ////////////////////   CHECK GALERKIN ORTHOGONALITY   ///////////////////////

  BCPtr nullBC;
  RHSPtr nullRHS;
  IPPtr nullIP;
  SolutionPtr solnPerturbation = Teuchos::rcp(new Solution(mesh, nullBC, nullRHS, nullIP) );

  map< int, vector<DofInfo> > infoMap = constructGlobalDofToLocalDofInfoMap(mesh);

  for (map< int, vector<DofInfo> >::iterator mapIt = infoMap.begin();
       mapIt != infoMap.end(); mapIt++)
  {
    int dofIndex = mapIt->first;
    vector< DofInfo > dofInfoVector = mapIt->second; // all the local dofs that map to dofIndex
    // create perturbation in direction du
    solnPerturbation->clear(); // clear all solns
    // set each corresponding local dof to 1.0
    for (vector< DofInfo >::iterator dofInfoIt = dofInfoVector.begin();
         dofInfoIt != dofInfoVector.end(); dofInfoIt++)
    {
      DofInfo info = *dofInfoIt;
      FieldContainer<double> solnCoeffs(info.basisCardinality);
      solnCoeffs(info.basisOrdinal) = 1.0;
      solnPerturbation->setSolnCoeffsForCellID(solnCoeffs, info.cellID, info.trialID, info.sideIndex);
    }
    //    solnPerturbation->setSolnCoeffForGlobalDofIndex(1.0,dofIndex);

    LinearTermPtr b_du =  convectionBF->testFunctional(solnPerturbation);
    FunctionPtr gradient = b_du->evaluate(err_rep_map, TestingUtilities::isFluxOrTraceDof(mesh,dofIndex)); // use boundary part only if flux
    double grad = gradient->integrate(mesh,10);
    if (!TestingUtilities::isFluxOrTraceDof(mesh,dofIndex) && abs(grad)>tol)  // if we're not single-precision zero FOR FIELDS
    {
      //      int cellID = mesh->getGlobalToLocalMap()[dofIndex].first;
      cout << "Failed testGalerkinOrthogonality() for fields with diff " << abs(grad) << " at dof " << dofIndex << "; info:" << endl;
      cout << dofInfoString(infoMap[dofIndex]);
      success = false;
    }
  }
  FieldContainer<double> errorJumps(mesh->numGlobalDofs()); //initialized to zero
  // just test fluxes ON INTERNAL SKELETON here
  set<GlobalIndexType> activeCellIDs = mesh->getActiveCellIDsGlobal();
  for (GlobalIndexType activeCellID : activeCellIDs)
  {
    ElementPtr elem = mesh->getElement(activeCellID);
    for (int sideIndex = 0; sideIndex < 4; sideIndex++)
    {
      ElementTypePtr elemType = elem->elementType();
      vector<int> localDofIndices = elemType->trialOrderPtr->getDofIndices(beta_n_u->ID(), sideIndex);
      for (int i = 0; i<localDofIndices.size(); i++)
      {
        int globalDofIndex = mesh->globalDofIndex(elem->cellID(), localDofIndices[i]);
        vector< DofInfo > dofInfoVector = infoMap[globalDofIndex];

        solnPerturbation->clear();
        TestingUtilities::setSolnCoeffForGlobalDofIndex(solnPerturbation,1.0,globalDofIndex);
        // also add in BCs
        for (int i = 0; i<bcGlobalIndices.dimension(0); i++)
        {
          TestingUtilities::setSolnCoeffForGlobalDofIndex(solnPerturbation,bcGlobalValues(i),bcGlobalIndices(i));
        }

        LinearTermPtr b_du =  convectionBF->testFunctional(solnPerturbation);
        FunctionPtr gradient = b_du->evaluate(err_rep_map, TestingUtilities::isFluxOrTraceDof(mesh,globalDofIndex)); // use boundary part only if flux
        double jump = gradient->integrate(mesh,10);
        errorJumps(globalDofIndex) += jump;
      }
    }
  }
  for (int i = 0; i<mesh->numGlobalDofs(); i++)
  {
    if (abs(errorJumps(i))>tol)
    {
      cout << "Failing Galerkin orthogonality test for fluxes with diff " << errorJumps(i) << " at dof " << i << endl;
      cout << dofInfoString(infoMap[i]);
      success = false;
    }
  }

  return success;
}