예제 #1
0
inline void matrix<T>::read(const matrix<U>& m)
{
    assert(m.nrow()*m.ncol()==nElements());
    T* out = p+nElements()-1;
    for(int i=m.nrow()-1; i >= 0; i--)
        for(int j=m.ncol()-1; j >= 0; j--)
            *out-- = static_cast<T>( m(i,j) );
}
예제 #2
0
tElement *tSelectionSet::prepend(tElement *el)
{
    while (nElements() > fMaxSelectableItems+1 && fMaxSelectableItems != -1) {
        removeElement(nElements()-1);
    }
    if (fAllowDublicates || !contains(el)){
        return tGroup::prepend(el);
    } else {
        return NULL;
    }
}
예제 #3
0
matrix<T>& matrix<T>::operator=(const matrix<T>& m)
{
    if(&m == this) return *this;
    if(m.nElements() != nElements()){
        free();
        alloc(m.m_rows, m.m_cols);
    } else {
        m_rows = m.m_rows;
        m_cols = m.m_cols;
    }
    for(int i = nElements()-1; i >= 0; i--)
        p[i] = m.p[i];
    return *this;
}
예제 #4
0
 void MineralEQ3::convertDGFormation() {
    /*
     * Ok let's get the element compositions and conversion factors.
     */
    int ne = nElements();
    doublereal na;
    doublereal ge;
    string ename;

    doublereal totalSum = 0.0;
    for (int m = 0; m < ne; m++) {
      na = nAtoms(0, m);
      if (na > 0.0) {
	ename = elementName(m);
	ge = LookupGe(ename);
	totalSum += na * ge;
      }
    }
    // Add in the charge
    // if (m_charge_j != 0.0) {
    // ename = "H";
      // ge = LookupGe(ename);
    // totalSum -= m_charge_j * ge;
    //}
    // Ok, now do the calculation. Convert to joules kmol-1
    doublereal dg = m_deltaG_formation_pr_tr * 4.184 * 1.0E3;
    //! Store the result into an internal variable.
    m_Mu0_pr_tr = dg + totalSum;
  }
예제 #5
0
matrix<T> matrix<T>::operator+(T a) const
{
    matrix<T> sum(m_rows,m_cols);
    for(int i = nElements()-1; i >= 0; i--)
        sum.p[i] = p[i] + a;
    return sum;
}
예제 #6
0
void MineralEQ3::convertDGFormation()
{
    // Ok let's get the element compositions and conversion factors.
    doublereal totalSum = 0.0;
    for (size_t m = 0; m < nElements(); m++) {
        double na = nAtoms(0, m);
        if (na > 0.0) {
            totalSum += na * LookupGe(elementName(m));
        }
    }
    // Ok, now do the calculation. Convert to joules kmol-1
    doublereal dg = m_deltaG_formation_pr_tr * toSI("cal/gmol");
    //! Store the result into an internal variable.
    m_Mu0_pr_tr = dg + totalSum;

    double Hcalc = m_Mu0_pr_tr + 298.15 * m_Entrop_pr_tr * toSI("cal/gmol");
    double DHjmol = m_deltaH_formation_pr_tr * toSI("kal/gmol");

    // If the discrepancy is greater than 100 cal gmol-1, print an error
    if (fabs(Hcalc -DHjmol) > 100 * toSI("cal/gmol")) {
        throw CanteraError("installMinEQ3asShomateThermoFromXML()",
                           "DHjmol is not consistent with G and S: {} vs {}",
                           Hcalc, DHjmol);
    }
}
예제 #7
0
std::auto_ptr<Bempp::Grid> SimpleTriangularGridManager::createGrid()
{
    Bempp::GridParameters params;
    params.topology = Bempp::GridParameters::TRIANGULAR;

    const int dimGrid = 2;
    arma::Col<Bempp::ctype> lowerLeft(dimGrid);
    arma::Col<Bempp::ctype> upperRight(dimGrid);
    arma::Col<unsigned int> nElements(dimGrid);
    lowerLeft.fill(0);
    upperRight.fill(1);
    nElements(0) = N_ELEMENTS_X;
    nElements(1) = N_ELEMENTS_Y;

    return Bempp::GridFactory::createStructuredGrid(params, lowerLeft, upperRight, nElements);
}
예제 #8
0
matrix<T> matrix<T>::operator*(T a) const
{
    matrix<T> prod(m_rows, m_cols);
    for(int i = nElements()-1; i >= 0; i--)
        prod.p[i] = a * p[i];
    return prod;
}
예제 #9
0
matrix<T> matrix<T>::operator-() const
{
    matrix<T> opp(m_rows, m_cols);
    for(int i = nElements()-1; i >= 0; i--)
        opp.p[i] = -p[i];
    return opp;
}
예제 #10
0
파일: Phase.cpp 프로젝트: anujg1991/cantera
void Phase::addSpecies(const std::string& name_, const doublereal* comp,
                       doublereal charge_, doublereal size_)
{
    freezeElements();
    m_speciesNames.push_back(name_);
    m_speciesCharge.push_back(charge_);
    m_speciesSize.push_back(size_);
    size_t ne = nElements();
    // Create a changeable copy of the element composition. We now change
    // the charge potentially
    vector_fp compNew(ne);
    for (size_t m = 0; m < ne; m++) {
        compNew[m] = comp[m];
    }
    double wt = 0.0;
    const vector_fp& aw = atomicWeights();
    if (charge_ != 0.0) {
        size_t eindex = elementIndex("E");
        if (eindex != npos) {
            doublereal ecomp = compNew[eindex];
            if (fabs(charge_ + ecomp) > 0.001) {
                if (ecomp != 0.0) {
                    throw CanteraError("Phase::addSpecies",
                                       "Input charge and element E compositions differ "
                                       "for species " + name_);
                } else {
                    // Just fix up the element E composition based on the input
                    // species charge
                    compNew[eindex] = -charge_;
                }
            }
        } else {
            addUniqueElementAfterFreeze("E", 0.000545, 0, 0.0,
                                        CT_ELEM_TYPE_ELECTRONCHARGE);
            ne = nElements();
            eindex = elementIndex("E");
            compNew.resize(ne);
            compNew[ne - 1] = - charge_;
        }
    }
    for (size_t m = 0; m < ne; m++) {
        m_speciesComp.push_back(compNew[m]);
        wt += compNew[m] * aw[m];
    }
    m_molwts.push_back(wt);
    m_kk++;
}
예제 #11
0
matrix<T> matrix<T>::operator-(const matrix<T>& m) const
{
    assert(m.m_rows == m_rows && m.m_cols == m_cols);
    matrix<T> sub(m_rows,m_cols);
    for(int i = nElements()-1; i >= 0; i--)
        sub.p[i] = p[i] - m.p[i];
    return sub;
}
예제 #12
0
 /*
  * Returns the number of atoms of element \c m in species \c k.
  */
 doublereal Constituents::nAtoms(int k, int m) const
 {
   const int m_mm = m_Elements->nElements();
   if (m < 0 || m >=m_mm)
     throw ElementRangeError("Constituents::nAtoms",m,nElements());
   if (k < 0 || k >= nSpecies())
     throw SpeciesRangeError("Constituents::nAtoms",k,nSpecies());
   return m_speciesComp[m_mm * k + m];
 }
예제 #13
0
/*
 *  The Cl- species is special in the sense that its single ion
 *  molality-based activity coefficient is used in the specification
 *  of the pH scale for single ions. Therefore, we need to know
 *  what species index Cl- is. If the species isn't in the species
 *  list then this routine returns -1, and we can't use the NBS
 *  pH scale.
 *
 *  Right now we use a restrictive interpretation. The species
 *  must be named "Cl-". It must consist of exactly one Cl and one E
 *  atom.
 */
size_t MolalityVPSSTP::findCLMIndex() const
{
    size_t indexCLM = npos;
    size_t eCl = npos;
    size_t eE = npos;
    size_t ne = nElements();
    string sn;
    for (size_t e = 0; e < ne; e++) {
        sn = elementName(e);
        if (sn == "Cl" || sn == "CL") {
            eCl = e;
            break;
        }
    }
    // We have failed if we can't find the Cl element index
    if (eCl == npos) {
        return npos;
    }
    for (size_t e = 0; e < ne; e++) {
        sn = elementName(e);
        if (sn == "E" || sn == "e") {
            eE = e;
            break;
        }
    }
    // We have failed if we can't find the E element index
    if (eE == npos) {
        return npos;
    }
    for (size_t k = 1; k < m_kk; k++) {
        doublereal nCl = nAtoms(k, eCl);
        if (nCl != 1.0) {
            continue;
        }
        doublereal nE = nAtoms(k, eE);
        if (nE != 1.0) {
            continue;
        }
        for (size_t e = 0; e < ne; e++) {
            if (e != eE && e != eCl) {
                doublereal nA = nAtoms(k, e);
                if (nA != 0.0) {
                    continue;
                }
            }
        }
        sn = speciesName(k);
        if (sn != "Cl-" && sn != "CL-") {
            continue;
        }

        indexCLM = k;
        break;
    }
    return indexCLM;
}
예제 #14
0
파일: Phase.cpp 프로젝트: anujg1991/cantera
void Phase::addSpecies(const std::string& name_, const doublereal* comp,
                       doublereal charge_, doublereal size_)
{
    compositionMap cmap;
    for (size_t i = 0; i < nElements(); i++) {
        if (comp[i]) {
            cmap[elementName(i)] = comp[i];
        }
    }
    Phase::addSpecies(Species(name_, cmap, 0, charge_, size_));
}
void ThermoPhase::setElementPotentials(const vector_fp& lambda)
{
    size_t mm = nElements();
    if (lambda.size() < mm) {
        throw CanteraError("setElementPotentials", "lambda too small");
    }
    if (!m_hasElementPotentials) {
        m_lambdaRRT.resize(mm);
    }
    scale(lambda.begin(), lambda.end(), m_lambdaRRT.begin(), 1.0/RT());
    m_hasElementPotentials = true;
}
예제 #16
0
  void LatticePhase::initThermo() {
    m_kk = nSpecies();
    m_mm = nElements();
    doublereal tmin = m_spthermo->minTemp();
    doublereal tmax = m_spthermo->maxTemp();
    if (tmin > 0.0) m_tmin = tmin;
    if (tmax > 0.0) m_tmax = tmax;
    m_p0 = refPressure();

    m_h0_RT.resize(m_kk);
    m_g0_RT.resize(m_kk);
    m_cp0_R.resize(m_kk);
    m_s0_R.resize(m_kk);
    setMolarDensity(m_molar_density);
  }
예제 #17
0
//====================================================================================================================
FixedChemPotSSTP::FixedChemPotSSTP(std::string Ename, doublereal val) :
    SingleSpeciesTP(),
    chemPot_(0.0)
{

    std::string pname = Ename + "Fixed";
    setID(pname);
    setName(pname);
    setNDim(3);
    addUniqueElement(Ename, -12345.);
    freezeElements();
    vector_fp ecomp(nElements(), 0.0);
    ecomp[0] = 1.0;
    double chrg = 0.0;
    SpeciesThermo* spth = new SimpleThermo();
    setSpeciesThermo(spth);
    addUniqueSpecies(pname, &ecomp[0], chrg, 0.0);
    double c[4];
    c[0] = 298.15;
    c[1] = val;
    c[2] = 0.0;
    c[3] = 0.0;
    m_spthermo->install(pname, 0, SIMPLE, c, 0.0, 1.0E30, OneAtm);
    freezeSpecies();
    initThermo();
    m_p0 = OneAtm;
    m_tlast = 298.15;
    setChemicalPotential(val);

    // Create an XML_Node entry for this species
    XML_Node* s = new XML_Node("species", 0);
    s->addAttribute("name", pname);
    std::string aaS = Ename + ":1";
    s->addChild("atomArray", aaS);
    XML_Node& tt = s->addChild("thermo");
    XML_Node& ss = tt.addChild("Simple");
    ss.addAttribute("Pref", "1 bar");
    ss.addAttribute("Tmax", "5000.");
    ss.addAttribute("Tmin", "100.");
    ss.addChild("t0", "298.15");
    ss.addChild("cp0", "0.0");
    std::string sval = fp2str(val);
    ss.addChild("h", sval);
    ss.addChild("s", "0.0");
    saveSpeciesData(0, s);
    delete s;
    s = 0;
}
예제 #18
0
    void LatticeSolidPhase::initThermo() {
        m_kk = nSpecies();
        m_mm = nElements();
        m_x.resize(m_kk);
        int n, nsp, k, loc = 0;
        doublereal ndens;
        m_molar_density = 0.0;
        for (n = 0; n < m_nlattice; n++) {
            nsp = m_lattice[n]->nSpecies();
            ndens = m_lattice[n]->molarDensity();
            for (k = 0; k < nsp; k++) {
                m_x[loc] = ndens * m_lattice[n]->moleFraction(k);
                loc++;
            }
            m_molar_density += ndens;
        }
        setMoleFractions(DATA_PTR(m_x));

//          const vector<string>& spnames = speciesNames();
//          int n, k, kl, namesize;
//          int nl = m_sitedens.size();
//          string s;
//          m_lattice.resize(m_kk,-1);
//          vector_fp conc(m_kk, 0.0);

//          compositionMap xx;
//          for (n = 0; n < nl; n++) {
//              for (k = 0; k < m_kk; k++) { 
//                  xx[speciesName(k)] = -1.0;
//              }
//              parseCompString(m_sp[n], xx);
//              for (k = 0; k < m_kk; k++) { 
//                  if (xx[speciesName(k)] != -1.0) {
//                      conc[k] = m_sitedens[n]*xx[speciesName(k)];
//                      m_lattice[k] = n;
//                  }
//              }

//          }
//          for (k = 0; k < m_kk; k++) {
//              if (m_lattice[k] == -1) {
//                  throw CanteraError("LatticeSolidPhase::"
//                      "setParametersFromXML","Species "+speciesName(k)
//                      +" not a member of any lattice.");
//              }                    
//          }
//          setMoleFractions(DATA_PTR(conc));
    }
void LatticeSolidPhase::initThermo()
{
    size_t kk = 0;
    size_t kstart = 0;
    lkstart_.resize(m_lattice.size() + 1);
    size_t loc = 0;

    for (size_t n = 0; n < m_lattice.size(); n++) {
        LatticePhase* lp = m_lattice[n];
        vector_fp constArr(lp->nElements());
        const vector_fp& aws = lp->atomicWeights();
        for (size_t es = 0; es < lp->nElements(); es++) {
            addElement(lp->elementName(es), aws[es], lp->atomicNumber(es),
                       lp->entropyElement298(es), lp->elementType(es));
        }
        kstart = kk;

        for (size_t k = 0; k < lp->nSpecies(); k++) {
            addSpecies(lp->species(k));
            kk++;
        }
        // Add in the lattice stoichiometry constraint
        if (n > 0) {
            string econ = fmt::format("LC_{}_{}", n, id());
            size_t m = addElement(econ, 0.0, 0, 0.0, CT_ELEM_TYPE_LATTICERATIO);
            size_t mm = nElements();
            size_t nsp0 = m_lattice[0]->nSpecies();
            for (size_t k = 0; k < nsp0; k++) {
                m_speciesComp[k * mm + m] = -theta_[0];
            }
            for (size_t k = 0; k < lp->nSpecies(); k++) {
                size_t ks = kstart + k;
                m_speciesComp[ks * mm + m] = theta_[n];
            }
        }
        size_t nsp = m_lattice[n]->nSpecies();
        lkstart_[n] = loc;
        for (size_t k = 0; k < nsp; k++) {
            m_x[loc] =m_lattice[n]->moleFraction(k) / (double) m_lattice.size();
            loc++;
        }
        lkstart_[n+1] = loc;
    }

    setMoleFractions(m_x.data());
    ThermoPhase::initThermo();
}
예제 #20
0
doublereal Phase::elementalMoleFraction(const size_t m) const
{
    checkElementIndex(m);
    double denom = 0;
    for (size_t k = 0; k < m_kk; k++) {
        double atoms = 0;
        for (size_t j = 0; j < nElements(); j++) {
            atoms += nAtoms(k, j);
        }
        denom += atoms * moleFraction(k);
    }
    doublereal numerator = 0.0;
    for (size_t k = 0; k != m_kk; ++k) {
        numerator += nAtoms(k, m) * moleFraction(k);
    }
    return numerator / denom;
}
예제 #21
0
    void ConstDensityThermo::initThermo() {
        m_kk = nSpecies();
        m_mm = nElements();
        doublereal tmin = m_spthermo->minTemp();
        doublereal tmax = m_spthermo->maxTemp();
        if (tmin > 0.0) m_tmin = tmin;
        if (tmax > 0.0) m_tmax = tmax;
        m_p0 = refPressure();

        m_h0_RT.resize(m_kk);
        m_g0_RT.resize(m_kk);
        m_expg0_RT.resize(m_kk);
        m_cp0_R.resize(m_kk);
        m_s0_R.resize(m_kk);
        m_pe.resize(m_kk, 0.0);
        m_pp.resize(m_kk);
    }
예제 #22
0
void IdealSolidSolnPhase::setToEquilState(const doublereal* lambda_RT)
{
    const vector_fp& grt = gibbs_RT_ref();

    // set the pressure and composition to be consistent with
    // the temperature,
    doublereal pres = 0.0;
    for (size_t k = 0; k < m_kk; k++) {
        m_pp[k] = -grt[k];
        for (size_t m = 0; m < nElements(); m++) {
            m_pp[k] += nAtoms(k,m)*lambda_RT[m];
        }
        m_pp[k] = m_Pref * exp(m_pp[k]);
        pres += m_pp[k];
    }
    setState_PX(pres, &m_pp[0]);
}
예제 #23
0
  void PecosGasPhase::initThermo() {
 
    m_mm = nElements();
    doublereal tmin = m_spthermo->minTemp();
    doublereal tmax = m_spthermo->maxTemp();
    if (tmin > 0.0) m_tmin = tmin;
    if (tmax > 0.0) m_tmax = tmax;
    m_p0 = refPressure();

    int leng = m_kk;
    m_h0_RT.resize(leng);
    m_g0_RT.resize(leng);
    m_expg0_RT.resize(leng);
    m_cp0_R.resize(leng);
    m_s0_R.resize(leng);
    m_pe.resize(leng, 0.0);
    m_pp.resize(leng);
  }
예제 #24
0
/// Re-ordering prism elements to correct OGS6 meshes with and without InSitu-Lib
void reorderNodes2(std::vector<MeshLib::Element*> &elements)
{
	std::size_t nElements (elements.size());
	for (std::size_t i=0; i<nElements; ++i)
	{
		const unsigned nElemNodes (elements[i]->getNBaseNodes());
		std::vector<MeshLib::Node*> nodes(elements[i]->getNodes(), elements[i]->getNodes() + nElemNodes);

		for(size_t j = 0; j < nElemNodes; ++j)
			if (elements[i]->getGeomType() == MeshLib::MeshElemType::PRISM)
			{
				for(size_t j = 0; j < 3; ++j)
				{
					elements[i]->setNode(j, nodes[j+3]);
					elements[i]->setNode(j+3, nodes[j]);
				}
				break;
			}
	}
}
예제 #25
0
  /*
   *
   * Add an element to the current set of elements in the current object.
   * @param symbol  symbol string
   * @param weight  atomic weight in kg/kmol.
   *
   *  The default weight is a special value, which will cause the
   *  routine to look up the actual weight via a string lookup.
   *
   *  There are two interfaces to this routine. The XML interface
   *  looks up the required parameters for the regular interface
   *  and then calls the base routine.
   */
  void Elements::
  addElement(const std::string& symbol, doublereal weight) 
  {
    if (weight == -12345.0) {
      weight = LookupWtElements(symbol);
      if (weight < 0.0) {
	throw ElementsFrozen("addElement");
      }
    }
    if (m_elementsFrozen) {
      throw ElementsFrozen("addElement");
      return;
    }
    m_atomicWeights.push_back(weight);
    m_elementNames.push_back(symbol);
#ifdef USE_DGG_CODE
    m_definedElements[symbol] = nElements() + 1;
#endif
    m_mm++;
  }
예제 #26
0
/// Re-ordering mesh elements to correct Data Explorer 5 meshes to work with Data Explorer 6.
void reorderNodes(std::vector<MeshLib::Element*> &elements)
{
	std::size_t nElements (elements.size());
	for (std::size_t i=0; i<nElements; ++i)
	{
		const unsigned nElemNodes (elements[i]->getNBaseNodes());
		std::vector<MeshLib::Node*> nodes(elements[i]->getNodes(), elements[i]->getNodes() + nElemNodes);

		switch (elements[i]->getGeomType())
		{
			case MeshLib::MeshElemType::TETRAHEDRON:
				for(size_t j = 0; j < 4; ++j)
					elements[i]->setNode(j, nodes[(j+1)%4]);
				break;
			case MeshLib::MeshElemType::PYRAMID:
				for(size_t j = 0; j < 5; ++j)
					elements[i]->setNode(j, nodes[(j+1)%5]);
				break;
			case MeshLib::MeshElemType::PRISM:
				for(size_t j = 0; j < 3; ++j)
				{
					elements[i]->setNode(j, nodes[j+3]);
					elements[i]->setNode(j+3, nodes[j]);
				}
				break;
			case MeshLib::MeshElemType::HEXAHEDRON:
				for(size_t j = 0; j < 4; ++j)
				{
					elements[i]->setNode(j, nodes[j+4]);
					elements[i]->setNode(j+4, nodes[j]);
				}
				break;
			default:
				for(size_t j = 0; j < nElemNodes; ++j)
					elements[i]->setNode(j, nodes[nElemNodes - j - 1]);
		}
	}
}
예제 #27
0
bool Phase::addSpecies(shared_ptr<Species> spec) {
    m_species[spec->name] = spec;
    vector_fp comp(nElements());
    for (const auto& elem : spec->composition) {
        size_t m = elementIndex(elem.first);
        if (m == npos) { // Element doesn't exist in this phase
            switch (m_undefinedElementBehavior) {
            case UndefElement::ignore:
                return false;

            case UndefElement::add:
                addElement(elem.first);
                comp.resize(nElements());
                m = elementIndex(elem.first);
                break;

            case UndefElement::error:
            default:
                throw CanteraError("Phase::addSpecies",
                    "Species '{}' contains an undefined element '{}'.",
                    spec->name, elem.first);
            }
        }
        comp[m] = elem.second;
    }

    m_speciesNames.push_back(spec->name);
    m_speciesIndices[spec->name] = m_kk;
    m_speciesCharge.push_back(spec->charge);
    m_speciesSize.push_back(spec->size);
    size_t ne = nElements();

    double wt = 0.0;
    const vector_fp& aw = atomicWeights();
    if (spec->charge != 0.0) {
        size_t eindex = elementIndex("E");
        if (eindex != npos) {
            doublereal ecomp = comp[eindex];
            if (fabs(spec->charge + ecomp) > 0.001) {
                if (ecomp != 0.0) {
                    throw CanteraError("Phase::addSpecies",
                                       "Input charge and element E compositions differ "
                                       "for species " + spec->name);
                } else {
                    // Just fix up the element E composition based on the input
                    // species charge
                    comp[eindex] = -spec->charge;
                }
            }
        } else {
            addElement("E", 0.000545, 0, 0.0, CT_ELEM_TYPE_ELECTRONCHARGE);
            ne = nElements();
            eindex = elementIndex("E");
            comp.resize(ne);
            comp[ne - 1] = - spec->charge;
        }
    }
    for (size_t m = 0; m < ne; m++) {
        m_speciesComp.push_back(comp[m]);
        wt += comp[m] * aw[m];
    }

    // Some surface phases may define species representing empty sites
    // that have zero molecular weight. Give them a very small molecular
    // weight to avoid dividing by zero.
    wt = std::max(wt, Tiny);
    m_molwts.push_back(wt);
    m_rmolwts.push_back(1.0/wt);
    m_kk++;

    // Ensure that the Phase has a valid mass fraction vector that sums to
    // one. We will assume that species 0 has a mass fraction of 1.0 and mass
    // fraction of all other species is 0.0.
    if (m_kk == 1) {
        m_y.push_back(1.0);
        m_ym.push_back(m_rmolwts[0]);
        m_mmw = 1.0 / m_ym[0];
    } else {
        m_y.push_back(0.0);
        m_ym.push_back(0.0);
    }
    invalidateCache();
    return true;
}
예제 #28
0
inline void matrix<T>::operator=(T a)
{
    for(int i = nElements()-1; i >= 0; i--)
        p[i] = a;
}
예제 #29
0
inline T& matrix<T>::operator() (int i)
{
    assert(i >= 0 && i < nElements());
    return p[i];
}
예제 #30
0
void matrix<T>::write(T* vect) const
{
    for(int i = nElements()-1; i >= 0; i--)
        vect[i] = p[i];
}