Exemplo n.º 1
0
void Bernstein::evalOnTet(const Point& pt, 
  const MultiIndex& deriv,
  Array<double>& result) const
{
  ADReal x = ADReal(pt[0], 0, 3);
  ADReal y = ADReal(pt[1], 1, 3);
  ADReal z = ADReal(pt[2], 2, 3);
  ADReal one(1.0, 3);
  
  Array<ADReal> tmp(result.length());

  if(order_==0)
  {
    tmp.resize(1);
    result.resize(1);
    tmp[0] = one;
  }
  else
  {
  }

  for (int i=0; i<tmp.length(); i++)
  {
    if (deriv.order()==0) result[i] = tmp[i].value();
    else 
      result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
  }
}
Exemplo n.º 2
0
Set<MultipleDeriv> applyTx(const Set<MultipleDeriv>& s,
  const MultiIndex& x)
{
  Set<MultipleDeriv> rtn;

  for (Set<MultipleDeriv>::const_iterator i=s.begin(); i!=s.end(); i++)
  {
    const MultipleDeriv& md = *i;
    for (MultipleDeriv::const_iterator j=md.begin(); j!=md.end(); j++)
    {
      const Deriv& d = *j;
      if (d.isFunctionalDeriv())
      {
        const MultiIndex& mi = d.opOnFunc().mi();
        MultiIndex miNew = mi+x;
        if (miNew.isValid())
        {
          Deriv dNew = d.derivWrtMultiIndex(miNew);
          MultipleDeriv mdNew = md;
          mdNew.erase(mdNew.find(d));
          mdNew.put(dNew);
          rtn.put(mdNew);
        }
      }
    }
  }
  return rtn;
}
Exemplo n.º 3
0
Set<MultipleDeriv> applyZx(const Set<MultipleDeriv>& W,
  const MultiIndex& x)
{
  Set<MultipleDeriv> rtn;

  TEUCHOS_TEST_FOR_EXCEPTION(x.order() < 0 || x.order() > 1, std::logic_error,
    "invalid multiindex " << x << " in this context");

  for (Set<MultipleDeriv>::const_iterator i=W.begin(); i!=W.end(); i++)
  {
    const MultipleDeriv& md = *i;
    TEUCHOS_TEST_FOR_EXCEPTION(md.order() != 1, std::logic_error,
      "Only first-order multiple functional derivatives "
      "should appear in this function. The derivative "
      << md << " is not first-order.");

    const Deriv& d = *(md.begin());

    if (d.isFunctionalDeriv())
    {
      /* */
      TEUCHOS_TEST_FOR_EXCEPTION(!d.canBeDifferentiated(),
        std::logic_error, "function signature " << d << " cannot be "
        "differentiated further spatially");
      /* accept a functional derivative if the associated function 
       * is not identically zero */
      const SymbolicFuncElement* sfe = d.symbFuncElem();
      TEUCHOS_TEST_FOR_EXCEPTION(sfe==0, std::logic_error, 
        "can't cast function in "
        << d << " to a SymbolicFuncElement");
      if (sfe && !sfe->evalPtIsZero()) rtn.put(md);
    }
  }
  return rtn;
}
void EdgeLocalizedBasis::evalOnTriangle(const Point& pt, 
  const MultiIndex& deriv,
  Array<double>& result) const
{
  ADReal x = ADReal(pt[0], 0, 2);
	ADReal y = ADReal(pt[1], 1, 2);
	ADReal one(1.0, 2);
	ADReal zero(0.0, 2);

  Array<ADReal> tmp;

  SUNDANCE_OUT(this->verb() > 3, "x=" << x.value() << " y="
    << y.value());

  result.resize(3);
  tmp.resize(3);

  bool onEdge2 = std::fabs(pt[1]) < 1.0e-14;
  bool onEdge0 = std::fabs(1.0-pt[0]-pt[1]) < 1.0e-14;
  bool onEdge1 = std::fabs(pt[0]) < 1.0e-14;
  
  TEUCHOS_TEST_FOR_EXCEPTION(!(onEdge0 || onEdge1 || onEdge2),
    std::runtime_error,
    "EdgeLocalizedBasis should not be evaluated at points not on edges");
  
  TEUCHOS_TEST_FOR_EXCEPTION((onEdge0 && onEdge1) || (onEdge1 && onEdge2)
    || (onEdge2 && onEdge0), std::runtime_error,
    "Ambiguous edge in EdgeLocalizedBasis::evalOnTriangle()");

  if (onEdge0)
  {
    tmp[0] = one;
    tmp[1] = zero;
    tmp[2] = zero;
  }
  if (onEdge1)
  {
    tmp[0] = zero;
    tmp[1] = one;
    tmp[2] = zero;
  }
  if (onEdge2)
  {
    tmp[0] = zero;
    tmp[1] = zero;
    tmp[2] = one;
  }


	for (int i=0; i<tmp.length(); i++)
  {
    SUNDANCE_OUT(this->verb() > 3,
      "tmp[" << i << "]=" << tmp[i].value() 
      << " grad=" << tmp[i].gradient());
    if (deriv.order()==0) result[i] = tmp[i].value();
    else 
      result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
  }
  
}
Exemplo n.º 5
0
void CubicHermite::evalOnTriangle(const Point& pt, 
  const MultiIndex& deriv,
  Array<double>& result) const

{
  result.resize(10);
  ADReal x = ADReal(pt[0], 0, 2);
  ADReal y = ADReal(pt[1], 1, 2);
  ADReal one(1.0, 2);
  
  Array<ADReal> tmp(10);

  SUNDANCE_OUT(this->verb() > 3, "x=" << x.value() << " y="
    << y.value());
 
  tmp[0] = 1 - 3*x*x + 2 * x*x*x - 13*x*y + 13*x*x*y - 3*y*y + 13 *x*y*y + 2 *y*y*y;
  tmp[1] = x - 2 *x*x + x*x*x - 3*x*y + 3*x*x*y + 2*x*y*y;
  tmp[2] = y - 3 *x *y + 2* x*x* y - 2* y*y + 3* x*y*y + y*y*y;
  tmp[3] = 3 * x*x - 2* x*x*x - 7* x* y + 7* x*x *y + 7* x*y*y;
  tmp[4] = -x*x + x*x*x + 2*x *y - 2* x*x* y - 2* x* y*y;
  tmp[5] = -x* y + 2* x*x* y + x* y*y;
  tmp[6] = -7* x* y + 7* x*x*y + 3* y*y + 7* x* y*y - 2* y*y*y;
  tmp[7] = -x *y + x*x* y + 2* x* y*y;
  tmp[8] = 2 *x *y - 2* x*x* y - y*y - 2* x* y*y + y*y*y;
  tmp[9] = 27* x *y - 27* x*x* y - 27* x* y*y;

  for (int i=0; i<tmp.length(); i++)
  {
    if (deriv.order()==0) result[i] = tmp[i].value();
    else 
      result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
  }
}
 inline
 bool MultiIndex<I, DIMENSION>::lex (const MultiIndex<I, DIMENSION>& lambda) const
 {
     return std::lexicographical_compare(FixedArray1D<I, DIMENSION>::begin(),
                                         FixedArray1D<I, DIMENSION>::end(),
                                         lambda.begin(), lambda.end());
 }
Expr SpectralPreprocessor::takeDeriv(const Expr& f, const MultiIndex& mi)
{
  TEUCHOS_TEST_FOR_EXCEPT(mi.order() > 1);

  
  const SpectralExpr* se 
    = dynamic_cast<const SpectralExpr*>(f.ptr().get());

  Expr d = new Derivative(mi.firstOrderDirection());
  int n = se->getSpectralBasis().nterms();
  
  if (se)
  {
    Array<Expr> c(n);
    for (int i=0; i<n; i++)
    {
      c[i] = d*se->getCoeff(i);
    }
    return new SpectralExpr(se->getSpectralBasis(), c);
  }
  else
  {
    return d*f;
  }
}
Exemplo n.º 8
0
JoinTips::JoinTips(MultiIndex& mind)
{
	limit = -1;
	count_only = false;
	for(int i = 0; i < mind.NoDimensions(); i++) {
		forget_now.push_back(mind.IsForgotten(i));
		distinct_only.push_back(false);
		null_only.push_back(false);
	}
}
Exemplo n.º 9
0
Set<MultipleDeriv> Xx(const MultiIndex& x)
{
  Set<MultipleDeriv> rtn;

  TEUCHOS_TEST_FOR_EXCEPTION(x.order() < 0 || x.order() > 1, std::logic_error,
    "invalid multiindex " << x << " in this context");

  MultipleDeriv xmd = makeMultiDeriv(coordDeriv(x.firstOrderDirection()));
  rtn.put(xmd);
  return rtn;
}
 inline
 bool MultiIndex<I, DIMENSION>::operator < (const MultiIndex& lambda) const
 {
        
     unsigned int r1(FixedArray1D<I,DIMENSION>::operator [] (0)),r2(multi_degree(lambda));
     for (unsigned int i(1); i < DIMENSION; i++)
     {
         r1 += FixedArray1D<I,DIMENSION>::operator [] (i);
     }
     return (r1<r2) || ((r1==r2) && (std::lexicographical_compare(FixedArray1D<I, DIMENSION>::begin(),
                                                                  FixedArray1D<I, DIMENSION>::end(),
                                                                  lambda.begin(), lambda.end()) ));
 }
Exemplo n.º 11
0
void Legendre::evalOnLine(const Point& pt,
  const MultiIndex& deriv,
  Array<double>& result) const
{
  result.resize(2+nrDOF_edge_);
  ADReal x = ADReal(pt[0],0,1);

  Array<ADReal> refAll(7);

  refAll[0] = 1-x;
  refAll[1] = x;
  refAll[2] = 2.44948974278318 * ( (2*x-1)*(2*x-1) - 1 ) / 4;
  refAll[3] = 3.16227766016838 * ( (2*x-1)*(2*x-1) - 1 ) * (2*x-1) / 4;
  refAll[4] = 3.74165738677394 * ( 5*(2*x-1)*(2*x-1)*(2*x-1)*(2*x-1) - 6*(2*x-1)*(2*x-1) + 1) / 16;
  refAll[5] = 4.24264068711929 * (2*x-1) * (7*(2*x-1)*(2*x-1)*(2*x-1)*(2*x-1) - 10*(2*x-1)*(2*x-1) + 3) / 16;
  refAll[6] = 4.69041575982343 * (21*(2*x-1)*(2*x-1)*(2*x-1)*(2*x-1)*(2*x-1) -
		                          35*(2*x-1)*(2*x-1)*(2*x-1)*(2*x-1) + 15*(2*x-1)*(2*x-1) - 1) / 32;


  for (int i=0; i<result.length(); i++)
  {
    if (deriv.order()==0) 
    {
      result[i] = refAll[i].value();
    }
    else 
    {
      result[i] = refAll[i].gradient()[0];
    }
  }  
  //SUNDANCE_OUT( true , "Legendre::evalOnLine result.length():" << result.length() );
  return;
}
Exemplo n.º 12
0
void CubicHermite::evalOnLine(const Point& pt, 
  const MultiIndex& deriv,
  Array<double>& result) const
{
  result.resize(4);
  ADReal x = ADReal(pt[0],0,1);
  Array<ADReal> tmp(4);

  tmp[0] = 1 + x * x * ( -3 + 2 * x );
  tmp[1] = x * ( 1 + (x - 2 ) * x );
  tmp[2] = ( 3 - 2*x ) * x * x;
  tmp[3] = (-1+x)*x*x;

  for (int i=0; i<tmp.length(); i++)
  {
    if (deriv.order()==0) 
    {
      result[i] = tmp[i].value();
    }
    else 
    {
      result[i] = tmp[i].gradient()[0];
    }
  }  
  return;
}
void EdgeLocalizedBasis::evalOnLine(const Point& pt, 
													const MultiIndex& deriv,
													Array<double>& result) const
{
	ADReal one(1.0, 1);
	result.resize(1);
	Array<ADReal> tmp(result.length());

  tmp[0] = one;

	for (int i=0; i<tmp.length(); i++)
		{
			if (deriv.order()==0) result[i] = tmp[i].value();
			else result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
		}
}
double TestEvalMediator::evalDummyBasis(int m, const MultiIndex& mi) const
{
  TEUCHOS_TEST_FOR_EXCEPTION(mi.order() > 1, std::runtime_error, 
                     "TestEvalMediator::evalDummyBasis found multiindex "
                     "order > 1. The bad multiindex was " << mi.toString());

  ADReal result = fields_[m].basis().evaluate(ADField::evalPoint());
  SUNDANCE_MSG3(verb(), "basis.value() " << result.value());
  SUNDANCE_MSG3(verb(), "basis.gradient() " << result.gradient());

  if (mi.order()==0)
    {
      return result.value();
    }
  else 
    {
      return result.gradient()[mi.firstOrderDirection()];
    }
}
Exemplo n.º 15
0
void R_s_k_2::draw_relevance(const float line_width, const int nb)
{
  MultiIndex mindex;
  FT min_value = (std::numeric_limits<FT>::max)();
  FT max_value = -(std::numeric_limits<FT>::max)();
  unsigned int nb_initial = 0;
  for (Finite_edges_iterator ei = m_dt.finite_edges_begin(); ei != m_dt.finite_edges_end(); ++ei)
  {
    Edge edge = *ei;
    if (m_dt.is_ghost(edge)) continue;
    FT value = m_dt.get_edge_relevance(edge); // >= 0

    nb_initial++;
    min_value = (std::min)(min_value, value);
    max_value = (std::max)(max_value, value);
    mindex.insert(PEdge(edge, value));
  }
  if (min_value == max_value) max_value += 1.0;

  viewer->glLineWidth(line_width);
  int nb_remove = (std::min)(nb, int(mindex.size()));

  viewer->glColor3d(0.5, 0.1, 0.1);
  for (int i = 0; i < nb_remove; ++i)
  {

    PEdge pedge = *(mindex.get<1>()).begin();
    (mindex.get<0>()).erase(pedge);
  }

  viewer->glColor3d(0.0, 0.5, 0.0);
  while (!mindex.empty())
  {
    PEdge pedge = *(mindex.get<1>()).begin();
    (mindex.get<0>()).erase(pedge);
    draw_edge(pedge.edge());
  }
}
Exemplo n.º 16
0
  static typename Point::value_type
  coeff(const MultiIndex& i,
        const Point& p) {
    typedef typename Point::value_type value_type;
    typedef Chebyshev<value_type,Q> C;

    value_type result(1);
    for (std::size_t k = 0; k < i.size(); ++k) {
      for (std::size_t q = 0; q < Q; ++q) {
        if (q != i[k]) {
          result *= (p[k] - C::x[q]) / (C::x[i[k]] - C::x[q]);
        }
      }
    }
    return result;
  }
SpatialDerivSpecifier SpatialDerivSpecifier::derivWrtMultiIndex(const MultiIndex& mi) const 
{
  if (isPartial() || isIdentity()) 
  {
    return SpatialDerivSpecifier(mi_+mi);
  }
  else if (mi.order()==0)
  {
    return *this;
  }
  else
  {
    TEST_FOR_EXCEPTION(true, InternalError, "cannot take an arbitrary "
      "spatial derivative of SDS=" << *this);
    return *this; // -Wall
  }
  
}
Exemplo n.º 18
0
  static std::array<typename Point::value_type,N>
  coeff(const MultiIndex& i,
        const std::array<Point,N>& p) {
    typedef typename Point::value_type value_type;
    typedef Chebyshev<value_type,Q> C;

    std::array<value_type,N> result;
    result.fill(1);

    for (std::size_t k = 0; k < i.size(); ++k) {
      for (std::size_t q = 0; q < Q; ++q) {
        if (q != i[k]) {
          for (std::size_t r = 0; r != N; ++r) {
            result[r] *= (p[r][k] - C::x[q]) / (C::x[i[k]] - C::x[q]);
          }
        }
      }
    }
    return result;
  }
Exemplo n.º 19
0
  static std::vector<typename Point::value_type>
  coeff(const MultiIndex& i,
        const std::vector<Point>& p) {
    typedef typename Point::value_type value_type;
    typedef Chebyshev<value_type,Q> C;

    std::vector<value_type> result(p.size(), 1);

    for (std::size_t k = 0; k != i.size(); ++k) {
      for (std::size_t q = 0; q != Q; ++q) {
        if (q != i[k]) {
          //const value_type xkxq = C::x[i[k]]-C::x[q]; // Don't help compiler!
          for (std::size_t r = 0; r != p.size(); ++r) {
            result[r] *= (p[r][k] - C::x[q]) / (C::x[i[k]] - C::x[q]);
          }
        }
      }
    }
    return result;
  }
Exemplo n.º 20
0
void Bernstein::evalOnLine(const Point& pt, 
  const MultiIndex& deriv,
  Array<double>& result) const
{
  ADReal x = ADReal(pt[0], 0, 1);
  ADReal one(1.0, 1);
  
  result.resize(order()+1);
  Array<ADReal> tmp(result.length());
  Array<double> x0(order()+1);
  
  if (order_ == 0)
  {
    tmp[0] = one;
  }
  else
  {
    double binom_cur = 1.0;
    for (int i=0; i<=order_; i++)
    {
      tmp[i] = one;

      for (int j=0;j<order_-i;j++) 
	    {
	      tmp[i] *= (1-x);
	    }
      for (int j=0;j<i;j++) 
	    {
	      tmp[i] *= x;
	    }
      tmp[i] *= binom_cur;
      binom_cur *= double(order()-i) / double(i+1);
    }
  }
  
  for (int i=0; i<tmp.length(); i++)
  {
    if (deriv.order()==0) result[i] = tmp[i].value();
    else result[i] = tmp[i].gradient()[0];
  }
}
Exemplo n.º 21
0
DiffOp::DiffOp(const MultiIndex& op, 
  const RCP<ScalarExpr>& arg)
  : UnaryExpr(arg), mi_(op), myCoordDeriv_(coordDeriv(op.firstOrderDirection())), requiredFunctions_(),
    ignoreFuncTerms_(false)
{}
Exemplo n.º 22
0
void Bernstein::evalOnTriangle(const Point& pt, 
  const MultiIndex& deriv,
  Array<double>& result) const

{
  ADReal x = ADReal(pt[0], 0, 2);
  ADReal y = ADReal(pt[1], 1, 2);
  ADReal one(1.0, 2);
  
  Array<ADReal> tmp;

  SUNDANCE_OUT(this->verb() > 3, "x=" << x.value() << " y="
    << y.value());
 
  if(order_==0) {
    result.resize(1);
    tmp.resize(1);
    tmp[0] = one;
  }
  else {
    int N = (order()+1)*(order()+2)/2;
    result.resize(N);
    tmp.resize(N);
    // these are the barycentric coordinates
    ADReal b1 = 1.0 - x - y;
    ADReal b2 = x;
    ADReal b3 = y;

    // will hold \binom{n}{\alpha_1}
    int bfcur = 0;

    for (int alpha1=order();alpha1>=0;alpha1--) 
    {
      for (int alpha2 = order()-alpha1;alpha2>=0;alpha2--)
      {
        int alpha3 = order() - alpha1 - alpha2;
        tmp[bfcur] = one;
        for (int i=0;i<alpha1;i++)
	      {
          tmp[bfcur] *= b1;
	      }
        for (int i=0;i<alpha2;i++) 
	      {
          tmp[bfcur] *= b2;
	      }
        for (int i=0;i<alpha3;i++)
	      {
          tmp[bfcur] *= b3;
	      }
        for (int i=2;i<=order();i++)
	      {
          tmp[bfcur] *= (double) i;
	      }
        for (int i=2;i<=alpha1;i++) 
	      {
          tmp[bfcur] /= (double) i;
	      }
        for (int i=2;i<=alpha2;i++) 
	      {
          tmp[bfcur] /= (double) i;
	      }
        for (int i=2;i<=alpha3;i++) 
	      {
          tmp[bfcur] /= (double) i;
	      }
        bfcur++;
      }
    }
  }

  for (int i=0; i<tmp.length(); i++)
  {
    if (deriv.order()==0) result[i] = tmp[i].value();
    else 
      result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
  }
}
Exemplo n.º 23
0
void Legendre::evalOnQuad(const Point& pt,
  const MultiIndex& deriv,
  Array<double>& result) const

{
  result.resize( 4 + 4*nrDOF_edge_ + nrDOF_face_);
  ADReal x = ADReal(pt[0], 0, 2);
  ADReal y = ADReal(pt[1], 1, 2);
  ADReal one(1.0, 2);
  
  Array<ADReal> refAllx(7);
  Array<ADReal> refAlly(7);

  refAllx[0] = 1-x;
  refAllx[1] = x;
  refAllx[2] = 2.44948974278318 * ( (2*x-1)*(2*x-1) - 1 ) / 4;
  refAllx[3] = 3.16227766016838 * ( (2*x-1)*(2*x-1) - 1 ) * (2*x-1) / 4;
  refAllx[4] = 3.74165738677394 * ( 5*(2*x-1)*(2*x-1)*(2*x-1)*(2*x-1) - 6*(2*x-1)*(2*x-1) + 1) / 16;
  refAllx[5] = 4.24264068711929 * (2*x-1) * (7*(2*x-1)*(2*x-1)*(2*x-1)*(2*x-1) - 10*(2*x-1)*(2*x-1) + 3) / 16;
  refAllx[6] = 4.69041575982343 * (21*(2*x-1)*(2*x-1)*(2*x-1)*(2*x-1)*(2*x-1) -
		                          35*(2*x-1)*(2*x-1)*(2*x-1)*(2*x-1) + 15*(2*x-1)*(2*x-1) - 1) / 32;

  refAlly[0] = 1-y;
  refAlly[1] = y;
  refAlly[2] = 2.44948974278318 * ( (2*y-1)*(2*y-1) - 1 ) / 4;
  refAlly[3] = 3.16227766016838 * ( (2*y-1)*(2*y-1) - 1 ) * (2*y-1) / 4;
  refAlly[4] = 3.74165738677394 * ( 5*(2*y-1)*(2*y-1)*(2*y-1)*(2*y-1) - 6*(2*y-1)*(2*y-1) + 1) / 16;
  refAlly[5] = 4.24264068711929 * (2*y-1) * (7*(2*y-1)*(2*y-1)*(2*y-1)*(2*y-1) - 10*(2*y-1)*(2*y-1) + 3) / 16;
  refAlly[6] = 4.69041575982343 * (21*(2*y-1)*(2*y-1)*(2*y-1)*(2*y-1)*(2*y-1) -
		                          35*(2*y-1)*(2*y-1)*(2*y-1)*(2*y-1) + 15*(2*y-1)*(2*y-1) - 1) / 32;

  SUNDANCE_OUT(this->verb() > 3, "x=" << x.value() << " y="
    << y.value());

  int sideIndex[4][2] = { {0,0} , {1,0} , {0,1} , {1,1}};
  int edgeIndex[4]    = { 0 , 1 , 1 , 0};
  int edgeMultI[4]    = { 0 , 0 , 1 , 1};
  int offs = 0;
  Array<ADReal> tmp(4 + 4*nrDOF_edge_ + nrDOF_face_);

  // loop over vertexes
  for (int i=0; i < 4 ; i++, offs++){
	  tmp[offs] = refAllx[sideIndex[i][0]] * refAlly[sideIndex[i][1]];
  }

  // loop over edges
  for (int i=0; i < 4 ; i++){
	  // loop over each DOF on the edge
	  if (edgeIndex[i] == 0){
		  for (int j = 0 ; j < nrDOF_edge_ ; j++ , offs++){
			  tmp[offs] = refAllx[2+j] * refAlly[edgeMultI[i]];
		  }
	  }
	  else
	  {
		  for (int j = 0 ; j < nrDOF_edge_ ; j++ , offs++){
			  tmp[offs] = refAllx[edgeMultI[i]] * refAlly[2+j];
		  }
	  }
  }

  // loop over all internal DOFs
  if ( nrDOF_face_ > 0 ){
	  // loop for each hierarchical layer
	  for (int hierarch = 0 ; hierarch < order_ - 3 ; hierarch++)
	  {
		  //SUNDANCE_OUT( true , "Legendre::evalOnQuad hierarch:" << hierarch );
		  // for each layer add the basis function
		  for (int i=0 ; i < hierarch+1 ; i++ , offs++)
		  {
			  //SUNDANCE_OUT( true , "Legendre::evalOnQuad offs:" << offs << " 2+i:" << 2+i << " , 2+(hierarch-1-i):" << 2+(hierarch-i));
			  tmp[offs] = refAllx[2+i] * refAlly[2+(hierarch-i)];
		  }
	  }
  }

  // compute the results
  for (int i=0; i<result.length(); i++)
  {
    if (deriv.order()==0) result[i] = tmp[i].value();
    else 
      result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
  }
  //SUNDANCE_OUT( true , "Legendre::evalOnQuad result.length():" << result.length() );
}
Exemplo n.º 24
0
void CurveEvalMediator
::evalDiscreteFuncElement(const DiscreteFuncElement* expr,
  const Array<MultiIndex>& multiIndices,
  Array<RCP<EvalVector> >& vec) const
{

	  int verbo = dfVerb();
	  Tabs tab1;
	  SUNDANCE_MSG2(verbo , tab1
	    << "CurveEvalMediator evaluating Discrete Function expr " << expr->toString());

	  const DiscreteFunctionData* f = DiscreteFunctionData::getData(expr);

	  TEUCHOS_TEST_FOR_EXCEPTION(f==0, std::logic_error,
	    "QuadratureEvalMediator::evalDiscreteFuncElement() called "
	    "with expr that is not a discrete function");

	  SUNDANCE_MSG2(verbo , tab1 << "After casting DiscreteFunctionData" << expr->toString());

	  RCP<Array<Array<double> > > localValues;
	  Array<int> cellLIDs_tmp(1);
	  Array<Point> phyPoints;
	  Array<Point> refPoints;
	  Array<Point> refDevs;
	  Array<Point> refNormal;
	  int nCells = cellLID()->size();

      RCP<const MapStructure> mapStruct;
	  int myIndex = expr->myIndex();
	  int nQuad = numQuadPtsForMaxCell_;
	  Array<int> k(multiIndices.size(),0);

	  Teuchos::BLAS<int,double> blas;

	  SUNDANCE_MSG2(verbo , tab1 << "After declaring BLAS: " << expr->toString());

	  // resize correctly the result vector
	  for (int i=0; i<multiIndices.size(); i++)
	  {
		  vec[i]->resize(nCells*nQuad);
	  }

	  // loop over each cell
	  for (int c=0; c<nCells; c++)
	  {
			int maxCellLID = (*cellLID())[c];
		    localValues = rcp(new Array<Array<double> >());
			SUNDANCE_MSG2(verbo , tab1 <<  "Cell:" << c <<  " of " << nCells << " , maxCellLID:" << maxCellLID );

			cellLIDs_tmp[0] = (*cellLID())[c];
			SUNDANCE_MSG2(verbo , tab1 <<  " Before calling f->getLocalValues:" << cellLIDs_tmp.size() <<
					" f==0 : " << (f==0) << " tmp:" << f->mesh().spatialDim());
			// - get local values from the DiscreteFunctionElementData
			mapStruct = f->getLocalValues(maxCellDim(), cellLIDs_tmp , *localValues);
			SUNDANCE_MSG2(verbo , tab1 <<  " After getting mapStruct:" << maxCellLID );
			SUNDANCE_MSG2(verbo , tab1 <<  " mapStruct->numBasisChunks():" << mapStruct->numBasisChunks() );
		    int chunk = mapStruct->chunkForFuncID(myIndex);
		    int funcIndex = mapStruct->indexForFuncID(myIndex);
		    int nFuncs = mapStruct->numFuncs(chunk);
			SUNDANCE_MSG2(verbo , tab1 <<  " chunk:" << chunk );
			SUNDANCE_MSG2(verbo , tab1 <<  " funcIndex:" << funcIndex );
			SUNDANCE_MSG2(verbo , tab1 <<  " nFuncs:" << nFuncs );

			// the chunk of the function
		    BasisFamily basis = rcp_dynamic_cast<BasisFamilyBase>(mapStruct->basis(chunk));
		    int nNodesTotal = basis.nReferenceDOFsWithFacets(maxCellType(), maxCellType());

			// - get intersection (reference)points from the mesh (if not existent than compute them)
			if ( mesh().hasCurvePoints( maxCellLID , paramcurve_.myID() ))
			{
				mesh().getCurvePoints( maxCellLID , paramcurve_.myID() , refPoints , refDevs , refNormal );
			}
			else // we have to calculate now the points
			{
				// calculate the intersection points
				CurveIntegralCalc::getCurveQuadPoints( maxCellType_ , maxCellLID , mesh() , paramcurve_ , quad_ ,
						refPoints, refDevs , refNormal);
				// store the intersection point in the mesh
				mesh().setCurvePoints( maxCellLID , paramcurve_.myID() , refPoints, refDevs , refNormal );
			}

			// loop over each multi-index
			SUNDANCE_MSG2(verbo , tab1 << " multiIndices.size()" << multiIndices.size() );
			for (int i=0; i<multiIndices.size(); i++)
			{

				int nDerivResults = 1;
				if ( multiIndices[i].order() == 1 ) nDerivResults = maxCellDim();

			    int pDir = 0;
			    int derivNum = 1;
				MultiIndex mi;
				SUNDANCE_MSG2(verbo , tab1 << " before asking anything i = " << i);
				SUNDANCE_MSG2(verbo , tab1 << " multiindex order : " << multiIndices[i].order());
				SUNDANCE_MSG2(verbo , tab1 << " multiindex : " << multiIndices[i] );
				if (multiIndices[i].order() > 0){
					pDir = multiIndices[i].firstOrderDirection();
					mi[pDir] = 1;
					derivNum = mesh().spatialDim();
				}

				Array<Array<double> > result(nQuad*derivNum);
				Array<Array<Array<double> > > tmp;

				int offs = nNodesTotal;

				// resize the result vector
				for (int deriv = 0 ; deriv < derivNum ; deriv++)
				{
                    // test weather we have to compute derivative
					if (multiIndices[i].order() > 0){
						// in case of derivatives we set one dimension
						MultiIndex mi_tmp;
						mi_tmp[deriv] = 1;
						SpatialDerivSpecifier deriv(mi_tmp);
						SUNDANCE_MSG2(verbo , tab1 << "computing derivatives : " << deriv << " on reference cell ");
						basis.refEval( maxCellType_ , refPoints , deriv, tmp , verbo );
					} else {
						SpatialDerivSpecifier deriv(mi);
						 // --- end eval basis functions
						SUNDANCE_MSG2(verbo , tab1 << "computing values reference cell ");
						basis.refEval( maxCellType_ , refPoints , deriv, tmp , verbo );
					}

					SUNDANCE_MSG2(verbo , tab1 << "resize result vector , offs:" << offs);
					for (int q=0; q<nQuad; q++){
						result[nQuad*deriv + q].resize(offs);
					}

				   	// copy the result in an other format
					SUNDANCE_MSG2(verbo , tab1 << "copy results ");
					int  offs1 = 0;
				    for (int q=0; q<nQuad; q++)
				    {
				    	offs1 = 0;
						for (int d=0; d<basis.dim(); d++)
						{
						   int nNodes = tmp[d][q].size();
					       for (int n=0; n<nNodes; n++ , offs1++ )
					       {
					          	result[nQuad*deriv + q][offs1] = tmp[d][q][n];
					       }
					    }
					}
				}// loop over all dimensional derivative

                // multiply the local results with the coefficients, (matrix vector OP)
				SUNDANCE_MSG2(verbo , tab1 << "summing up values , funcIndex:" << funcIndex << " offs:" << offs);
				for (int deriv = 0 ; deriv < derivNum ; deriv++)
				{
					for (int q=0; q<nQuad; q++)
					{
						double sum = 0.0;
						// sum over nodes
						for (int n = 0 ; n < offs ; n++){
							sum = sum + result[nQuad*deriv + q][n] * (*localValues)[chunk][funcIndex*offs + n];
						}
						// sum up the result in the 0th element
						result[nQuad*deriv + q][0] = sum;
					}
				}

			    // multiply the result if necesary with the inverse of the Jacobian
				const CellJacobianBatch& J = JTrans();
				if (mi.order()==1)
				{
					Tabs tab1;
					Tabs tab2;
				    SUNDANCE_MSG2(verbo, tab2 << "Jacobian batch nCells=" << J.numCells());
			        SUNDANCE_MSG2(verbo, tab2 << "Jacobian batch cell dim=" << J.cellDim());
			        SUNDANCE_MSG2(verbo, tab2 << "Jacobian batch spatial dim=" << J.spatialDim());
                    // we just multiply the derivative direction component
			        Array<double> invJ;
			        J.getInvJ(c, invJ);
					for (int q=0; q<nQuad; q++)
					{
						double sum = 0.0;
						for (int deriv = 0 ; deriv < derivNum ; deriv++)
						{
							// multiply one row from the J^{-T} matrix with the gradient vector
							sum = sum + result[nQuad*deriv + q][0] * invJ[derivNum*pDir + deriv];
						}
						// the resulting derivative on the physical cell in the "pDir" direction
						result[q][0] = sum;
					}
			    }

				// --- just copy the result to the "vec" back, the result should be in the  "result[q][0]" place----
				//SUNDANCE_MSG2(verbo , tab1 << "copy results back ");
				double* vecPtr = vec[i]->start();
				for (int q=0; q<nQuad; q++, k[i]++)
				{
					vecPtr[k[i]] = result[q][0];
				}
				SUNDANCE_MSG2(verbo , tab1 << " END copy results back ");
			} // --- end loop multiindex
			SUNDANCE_MSG2(verbo , tab1 << " END loop over multiindex ");
	}// --- end loop over cells
	SUNDANCE_MSG2(verbo , tab1 << " END loop over cells ");
}