コード例 #1
0
void AbstractTetrahedralElement<ELEMENT_DIM, SPACE_DIM>::CalculateInverseJacobian(c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian, double& rJacobianDeterminant, c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian)
{
    assert(ELEMENT_DIM <= SPACE_DIM);
    CalculateJacobian(rJacobian, rJacobianDeterminant);

    // CalculateJacobian should make sure that the determinant is not close to zero (or, in fact, negative)
    assert(rJacobianDeterminant > 0.0);
    rInverseJacobian = Inverse(rJacobian);
}
コード例 #2
0
AbstractTetrahedralElement<ELEMENT_DIM, SPACE_DIM>::AbstractTetrahedralElement(unsigned index, const std::vector<Node<SPACE_DIM>*>& rNodes)
    : AbstractElement<ELEMENT_DIM, SPACE_DIM>(index, rNodes)
{
    // Sanity checking
    unsigned num_vectices = ELEMENT_DIM+1;

    double det;

    if (SPACE_DIM == ELEMENT_DIM)
    {
        // This is so we know it's the first time of asking
        // Create Jacobian
        c_matrix<double, SPACE_DIM, ELEMENT_DIM> jacobian;
        try
        {
            CalculateJacobian(jacobian, det);
        }
        catch (Exception)
        {
            // if the Jacobian is negative the orientation of the element is probably
            // wrong, so swap the last two nodes around.

            this->mNodes[num_vectices-1] = rNodes[num_vectices-2];
            this->mNodes[num_vectices-2] = rNodes[num_vectices-1];

            CalculateJacobian(jacobian, det);
            // If determinant < 0 then element nodes are listed clockwise.
            // We want them anticlockwise.
            assert(det > 0.0);
        }
    }
    else
    {
        //This is not a full-dimensional element
        c_vector<double, SPACE_DIM> weighted_direction;
        CalculateWeightedDirection(weighted_direction, det);
    }

}
コード例 #3
0
ファイル: mchem.c プロジェクト: rfinkelnburg/MetPhoMod
void BoxChemStep(int i, int j, int k, long dt,
		 const Vector *sunpos, double *photorate)
{
  double f[MAXSUBST], vv[MAXSUBST], fact, err, origh2o;
  int indx[MAXSUBST], il, jl, nit;
  ProductionDesc *p;
  BOOL repeatit = FALSE;
  gli.i = i; gli.j = j; gli.k = k; gli.loc = k*layer+i*row+j;
  origh2o = g[HUMIDITY][gli.loc];
  g[HUMIDITY][gli.loc] *= 1.608e9;
  CalcRateConstants(AbsoluteTemp(g[TEMP][gli.loc], pp[k], origh2o),
		    dt, density[k], pp[k], sunpos->z, photorate);
  for (il = nsubst; il--; )  {
    /*	  if (CONZ(subst[il].subs) < 0.)
	  printf("Warning: Substance %s got negative: %le\n",
	  subst[il].name, CONZ(subst[il].subs)); */
    if (CONZ(subst[il].subs) < 1.e-30)  /* can't really handle such small concentrations */
      CONZ(subst[il].subs) = 0.;
  }
  CalcRates();
  for (il = nsubst; il--; )  {
    subst[il].oldc = CONZ(subst[il].subs);
    subst[il].take_as_fast = 0;
  }
  /*	CalcSlowSubst();  Aenderung am 17.9.97! */
  do  {
    nit = 0;
    while (1)  {
      jcb = CalculateJacobian(jcb);
      err = 0.;
      for (il = nfast; il--; )  {
	err += fabs((f[il] = CONZ(fast[il]->subs) - fast[il]->dcdt - fast[il]->oldc) /
		    (CONZ(fast[il]->subs) > 1.e-7 ? CONZ(fast[il]->subs) : 1.));
      }
      if (!repeatit && err < 1.e-5)  break;
      if (++nit > 500)  {
	printf("Chemistry is not converging at point %i/%i/%i\n", i, j, k);
	PrintConcentrations();
	PrintRates(REACTION_RATES);
	break;
      }
      if (LUdecomp(nfast, jcb, indx, &fact, vv))  {
	printf("Matrix is singular (in ChemicalTimeStep) at point %d/%d/%d!\n",
	       i, j, k);
	plausible = FALSE;
	return;
      }
      /*	    if (i == 10 && j == 4 && k == 1)
		    PrintRates(REACTION_RATES);
		    PrintMatrix(nfast, jcb, f);  */
      LUbackSub(nfast, jcb, indx, f);
      repeatit = 0;
      for (il = nfast; il--; )  {
	CONZ(fast[il]->subs) -= f[il];
	if (CONZ(fast[il]->subs) < 0.)  {
	  /*		printf("Warning: Substance %s got negative: %le\n",
			fast[il]->name, CONZ(fast[il]->subs));  */
	  CONZ(fast[il]->subs) = 0.;
	  repeatit = 1;
	}
      }
    }
    repeatit = 0;
    CalcSlowSubst();
    for (il = nfast; il--; )  {
      if (!fast[il]->oldc || 
	  fabs(CONZ(fast[il]->subs) - fast[il]->oldc) < 0.1 * fast[il]->oldc)  {
	fast[il]->take_as_fast = 0;
      }
    }
    for (il = nslow; il--; )  {
      if (CONZ(slow[il]->subs) < 0.)  {
	slow[il]->take_as_fast = repeatit = 1;
      }
    }
    if (repeatit)  {
      printf("repeating chemistry at point %i/%i/%i\n", i, j, k);
      CalcRates();
    }
  }  while (repeatit);
  for (p = prodd; p; p = p->next)
    p->pps[gli.loc] = (CONZ(p->subs) - subst[p->subs - SUBS + 1].oldc) /
      (double)dt;
  g[HUMIDITY][k*layer+i*row+j] = origh2o;
}