Ejemplo n.º 1
0
TestFunction::TestFunction(const BasisFamily& basis, 
                                 const SpectralBasis& spBasis,
                                 const std::string& name)
  : TestFunctionStub(name, spBasis, vectorDimStructure(basis)[0].first,
    vectorDimStructure(basis)[0].second,
    rcp(new TestFunctionData(replicate(basis, spBasis.nterms())))), 
    FuncWithBasis(replicate(basis, spBasis.nterms()))
{;}
Ejemplo n.º 2
0
Expr Expr::operator/(const Expr& other) const 
{
  TimeMonitor t(opTimer());

  /* if the right operand is a list, this operation
   * makes no sense */
  TEUCHOS_TEST_FOR_EXCEPTION(other.size() != 1,
    std::runtime_error, 
    "Expr::operator/ detected division by a non-scalar "
    "expression " << toString());

  TEUCHOS_TEST_FOR_EXCEPTION(other.isSpectral(), std::logic_error, 
    "Division by a Spectral Expr is not yet defined");

  /* If other is complex, transform to make the denominator real */
  if (other.isComplex())
  {
    Expr magSq = other.real()*other.real() + other.imag()*other.imag();
    return (*this) * other.conj() / magSq;
  }

  /* If I'm complex and the other is not, distribute division over re and im */
  if (isComplex() && !other.isComplex())
  {
    return new ComplexExpr(real()/other, imag()/other);
  }

  /* If I'm spectral and the other is not, distribute division over coefficients */
  if (isSpectral() && !other.isSpectral()  && !other.isComplex())
  {
    const SpectralExpr* se 
      = dynamic_cast<const SpectralExpr*>((*this)[0].ptr().get());

    SpectralBasis basis = se->getSpectralBasis();
    Array<Expr> coeff(basis.nterms());
	  
    for(int i=0; i<basis.nterms(); i++)
    {
      coeff[i] = se->getCoeff(i)/ other[0];
    }
    Expr rtn = new SpectralExpr( basis, coeff);
    return rtn;
  }

  /* if we are a scalar, do simple scalar division */
  if (this->size()==1)
  {
    return (*this)[0].divide(other[0]);
  }

  /* otherwise, divide each element of the left by the right operand */
  Array<Expr> rtn(this->size());
  for (int i=0; i<this->size(); i++)
  {
    rtn[i] = (*this)[i] / other;
  }
  return new ListExpr(rtn);
}
Ejemplo n.º 3
0
DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
  const SpectralBasis& spBasis,
  const VectorType<double>& vecType,
  int setupVerb)
  : setupVerb_(setupVerb),
    map_(), 
    mesh_(mesh), 
    subdomains_(),
    basis_(),
    vecSpace_(), 
    vecType_(vecType),
    ghostImporter_()
  ,transformationBuilder_(0)
{
  init(maximalRegions(basis.size() * spBasis.nterms()), 
    replicate(basis, spBasis.nterms()));
}
SpectralExpr::SpectralExpr(const SpectralBasis& sbasis, const Expr& coeffs)
  : ScalarExpr(), 
    coeffs_(),
    sbasis_(sbasis)

{
  int nterms = sbasis.nterms();
  coeffs_.resize(nterms);
  for (int i=0; i<nterms; i++)
    coeffs_[i] = coeffs[i];
}
Expr SpectralPreprocessor::projectSpectral(
  const Array<Array<Expr> >& terms)
{
  Expr rtn = 0.0;
  
  for (int t=0; t<terms.size(); t++)
  {
    Expr test;
    Expr deterministic;
    Array<Expr> specs;
    Array<Expr> testCoeffs;
    Array<Array<Expr> > specCoeffs;
    Array<SpectralBasis> specBas;

    parseProduct(terms[t], test, deterministic, specs);
    
    const SpectralExpr* specTest 
      = dynamic_cast<const SpectralExpr*>(test.ptr().get());
    TEUCHOS_TEST_FOR_EXCEPT(specTest==0);

    SpectralBasis testBasis = specTest->getSpectralBasis();
    for (int i=0; i<testBasis.nterms(); i++)
    {
      testCoeffs.append(specTest->getCoeff(i));
    } 

    for (int i=0; i<specs.size(); i++)
    {
      const SpectralExpr* s 
        = dynamic_cast<const SpectralExpr*>(specs[i].ptr().get());
      SpectralBasis bas = s->getSpectralBasis();
      specBas.append(bas);
      Array<Expr> c;
      for (int j=0; j<bas.nterms(); j++)
      {
        c.append(s->getCoeff(j));
      }
      specCoeffs.append(c);
    }

    if (specs.size()==0)
    {
      for (int i=0; i<testBasis.nterms(); i++)
      {
        rtn = rtn + testCoeffs[i]*deterministic;
      } 
    }
    else if (specs.size()==1)
    {
      for (int i=0; i<testBasis.nterms(); i++)
      {
        rtn = rtn + testCoeffs[i]*specCoeffs[0][i]*deterministic;
      } 
    }
    else if (specs.size()==2U)
    {
      for (int i=0; i<testBasis.nterms(); i++)
      {
        for (int j=0; j<specBas[0].nterms(); j++)
        {
          for (int k=0; k<specBas[1].nterms(); k++)
          {
            double w = testBasis.expectation(
              specBas[0].getElement(j), specBas[1].getElement(k), i) 
              / testBasis.expectation(0,i,i);
            if (w==0.0) continue;
            rtn = rtn + w*testCoeffs[i]
              *specCoeffs[0][j]*specCoeffs[1][k]*deterministic;
          }
        }
      } 
    }
    else
    {
      TEUCHOS_TEST_FOR_EXCEPTION(specs.size() > 2, std::runtime_error,
        "not ready to work with more than two spectral unks");
    }
  }

  return rtn;
}
Ejemplo n.º 6
0
int main(int argc, char** argv)
{
  try
    {
      MPISession::init(&argc, (void***)&argv);
      

      Expr::showAllParens() = true;

      Expr x = new CoordExpr(0);
      Expr y = new CoordExpr(1);
      Expr z = new CoordExpr(2);

      Expr dx = new Derivative(0);

      int ndim = 2;
      int order = 2;

      SpectralBasis SB = new HermiteSpectralBasis(ndim, order);

      Expr u = new UnknownFunctionStub("u", SB);
      Expr v = new TestFunctionStub("v", SB);
      Expr w = new UnknownFunctionStub("w", SB);
     
      Array<Expr> Ex1(6);
      Ex1[0] = 1.0;
      Ex1[1] = x;
      Ex1[2] = 0.0;
      Ex1[3] = x*y;
      Ex1[4] = x+y;
      Ex1[5] = y;

      Expr SE1 = new SpectralExpr(SB, Ex1);


      Array<Expr> Ex2(6);
      Ex2[0] = -3.0*x;
      Ex2[1] = 0.0;
      Ex2[2] = -y;
      Ex2[3] = x-y;
      Ex2[4] = -4.0*y + 2.0*x;
      Ex2[5] = 0.0;

      Expr SE2 = new SpectralExpr(SB, Ex2);

      Expr G = x*x;

      Expr Sum  = (dx*v) * (dx*u) + v*x;

      Handle<CellFilterStub> domain = rcp(new CellFilterStub());
      Handle<QuadratureFamilyStub> quad = rcp(new QuadratureFamilyStub(1));

      Expr eqn = Integral(domain, Sum, quad);

      const SpectralExpr* se = dynamic_cast<const SpectralExpr*>(Sum.ptr().get());
      if (se != 0)
        {
          SpectralBasis basis = se->getSpectralBasis();

          for(int i=0; i< basis.nterms(); i++)
            cout << se->getCoeff(i) << std::endl;
        }

      cout << Sum << std::endl << std::endl; 

      cout << eqn << std::endl << std::endl; 


    }
  
  catch(std::exception& e)
    {
      std::cerr << e.what() << std::endl;
    }
  MPISession::finalize();
}
Ejemplo n.º 7
0
bool BlockStochPoissonTest1D()
{
  /* We will do our linear algebra using Epetra */
  VectorType<double> vecType = new EpetraVectorType();

  /* Read a mesh */
  MeshType meshType = new BasicSimplicialMeshType();
  int nx = 32;
  MeshSource mesher = new PartitionedLineMesher(0.0, 1.0, nx, 
    meshType);
  Mesh mesh = mesher.getMesh();

  /* Create a cell filter that will identify the maximal cells
   * in the interior of the domain */
  CellFilter interior = new MaximalCellFilter();
  CellFilter pts = new DimensionalCellFilter(0);
  CellFilter left = pts.subset(new CoordinateValueCellPredicate(0,0.0));
  CellFilter right = pts.subset(new CoordinateValueCellPredicate(0,1.0));

  Expr x = new CoordExpr(0);

  /* Create the stochastic coefficients */
  int nDim = 1;
  int order = 6;
#ifdef HAVE_SUNDANCE_STOKHOS
  Out::root() << "using Stokhos hermite basis" << std::endl;
  SpectralBasis pcBasis = new Stokhos::HermiteBasis<int,double>(order);
#else
  Out::root() << "using George's hermite basis" << std::endl;
  SpectralBasis pcBasis = new HermiteSpectralBasis(nDim, order);
#endif
    
  Array<Expr> q(pcBasis.nterms());
  Array<Expr> kappa(pcBasis.nterms());
  Array<Expr> uEx(pcBasis.nterms());

  double a = 0.1;

  q[0] = -2 + pow(a,2)*(4 - 9*x)*x - 2*pow(a,3)*(-1 + x)*(1 + 3*x*(-3 + 4*x));
  q[1] = -(a*(-3 + 10*x + 2*a*(-1 + x*(8 - 9*x +
          a*(-4 + 3*(5 - 4*x)*x + 12*a*(-1 + x)*(1 + 5*(-1 + x)*x))))));
  q[2] = a*(-4 + 6*x + a*(1 - x*(2 + 3*x) + a*(4 - 28*x + 30*pow(x,2))));
  q[3] = -(pow(a,2)*(-3 + x*(20 - 21*x +
        a*(-4 + 3*(5 - 4*x)*x + 24*a*(-1 + x)*(1 + 5*(-1 + x)*x)))));
  q[4] = pow(a,3)*(1 + x*(-6 + x*(3 + 4*x)));
  q[5] = -4*pow(a,4)*(-1 + x)*x*(1 + 5*(-1 + x)*x);
  q[6] = 0.0;

  uEx[0] = -((-1 + x)*x);
  uEx[1] = -(a*(-1 + x)*pow(x,2));
  uEx[2] = a*pow(-1 + x,2)*x;
  uEx[3] = pow(a,2)*pow(-1 + x,2)*pow(x,2);
  uEx[4] = 0.0;
  uEx[5] = 0.0;
  uEx[6] = 0.0;

  kappa[0] = 1.0;
  kappa[1] = a*x;
  kappa[2] = -(pow(a,2)*(-1 + x)*x);

  kappa[3] = 1.0; // unused
  kappa[4] = 1.0; // unused
  kappa[5] = 1.0; // unused
  kappa[6] = 1.0; // unused


  Array<Expr> uBC(pcBasis.nterms());
  for (int i=0; i<pcBasis.nterms(); i++) uBC[i] = 0.0;

  int L = nDim+2;
  int P = pcBasis.nterms();
  Out::os() << "L = " << L << std::endl;
  Out::os() << "P = " << P << std::endl;
    
  /* Create the unknown and test functions. Do NOT use the spectral
   * basis here */
  Expr u = new UnknownFunction(new Lagrange(4), "u");
  Expr v = new TestFunction(new Lagrange(4), "v");

  /* Create differential operator and coordinate function */
  Expr dx = new Derivative(0);
  Expr grad = dx;


  /* We need a quadrature rule for doing the integrations */
  QuadratureFamily quad = new GaussianQuadrature(12);

  /* Now we create problem objects to build each $K_j$ and $f_j$.
   * There will be L matrix-vector pairs */
  Array<Expr> eqn(P);
  Array<Expr> bc(P);
  Array<LinearProblem> prob(P);
  Array<LinearOperator<double> > KBlock(L);
  Array<Vector<double> > fBlock(P);
  Array<Vector<double> > solnBlock;

  for (int j=0; j<P; j++)
  {
    eqn[j] = Integral(interior, kappa[j]*(grad*v)*(grad*u) + v*q[j], quad);
    bc[j] = EssentialBC(left+right, v*(u-uBC[j]), quad);
    prob[j] = LinearProblem(mesh, eqn[j], bc[j], v, u, vecType); 
    if (j<L) KBlock[j] = prob[j].getOperator();
    fBlock[j] = -1.0*prob[j].getSingleRHS();
  }

  /* Read the solver to be used on the diagonal blocks */
  LinearSolver<double> diagSolver 
    = LinearSolverBuilder::createSolver("amesos.xml");

    
  double convTol = 1.0e-12;
  int maxIters = 30;
  int verb = 1;
  StochBlockJacobiSolver solver(diagSolver, pcBasis,
    convTol, maxIters, verb);
    
  solver.solve(KBlock, fBlock, solnBlock);

  /* write the solution */
  FieldWriter w = new MatlabWriter("Stoch1D");
  w.addMesh(mesh);
  DiscreteSpace discSpace(mesh, new Lagrange(4), vecType);
  for (int i=0; i<P; i++)
  {
    L2Projector proj(discSpace, uEx[i]);
    Expr ue_i = proj.project();
    Expr df = new DiscreteFunction(discSpace, solnBlock[i]);
    w.addField("u["+ Teuchos::toString(i)+"]", 
      new ExprFieldWrapper(df));
    w.addField("uEx["+ Teuchos::toString(i)+"]", 
      new ExprFieldWrapper(ue_i));
  }
  w.write();

  double totalErr2 = 0.0;
  DiscreteSpace discSpace4(mesh, new Lagrange(4), vecType);
  for (int i=0; i<P; i++)
  {
    Expr df = new DiscreteFunction(discSpace4, solnBlock[i]);
    Expr errExpr = Integral(interior, pow(uEx[i]-df, 2.0), quad);
    Expr scaleExpr = Integral(interior, pow(uEx[i], 2.0), quad);
    double errSq = evaluateIntegral(mesh, errExpr);
    double scale = evaluateIntegral(mesh, scaleExpr);
    if (scale > 0.0) 
      Out::os() << "mode i=" << i << " error=" << sqrt(errSq/scale) << std::endl;
    else
      Out::os() << "mode i=" << i << " error=" << sqrt(errSq) << std::endl;
  }
    
  double tol = 1.0e-12;
    
  return SundanceGlobal::checkTest(sqrt(totalErr2), tol);
}
Ejemplo n.º 8
0
Expr Expr::operator-() const 
{
  TimeMonitor t(opTimer());
  TimeMonitor t1(unaryMinusTimer());
  Tabs tabs;

  if (this->isComplex())
  {
    return new ComplexExpr(-real(), -imag());
  }

  /* if we are a real scalar, process the unary minus here */
  if (this->size()==1)
  {
    /* if we are spectral, thread unary minus over coeffs */
    const SpectralExpr* se 
      = dynamic_cast<const SpectralExpr*>((*this)[0].ptr().get());
    if (se != 0)
    {
      SpectralBasis basis = se->getSpectralBasis();
      Array<Expr> coeff(basis.nterms());
	
      for(int i=0; i<basis.nterms(); i++)
      {
        coeff[i] = - se->getCoeff(i);
      }
      Expr rtn = new SpectralExpr( basis, coeff);
      return rtn;
    }

    /* Test for some special cases that can be dealt with efficiently */
    const ConstantExpr* c 
      = dynamic_cast<const ConstantExpr*>((*this)[0].ptr().get());
    const UnaryMinus* u 
      = dynamic_cast<const UnaryMinus*>((*this)[0].ptr().get());
    /* if we are a constant, just modify the constant */
    if (c != 0)
    {
      if (c->value()==0.0)
      {
        return new ZeroExpr();
      }
      else
      {
        return new ConstantExpr(-1.0 * c->value());
      }
    }
    else if (u != 0) /* if we are already a unary minus, apply -(-x) --> x */
    {
      return u->arg();
    }
    else /* no special structure, so return a UnaryMinusExpr */
    {
      RCP<ScalarExpr> sThis 
        = rcp_dynamic_cast<ScalarExpr>((*this)[0].ptr());
      TEUCHOS_TEST_FOR_EXCEPTION(sThis.get()==NULL, std::logic_error,
        "Expr::operator-(): Operand " << (*this)[0].toString() 
        << " is a non-scalar expression. All list structure "
        "should have been handled before this point");
      return new UnaryMinus(sThis);
    }
  }

  /* otherwise, distribute the sign change over the list */
  Array<Expr> rtn(this->size());
  for (int i=0; i<this->size(); i++)
  {
    rtn[i] = -((*this)[i]);
  }
  return new ListExpr(rtn);
}