Пример #1
0
bool is_lt(expr const & a, expr const & b, bool use_hash) {
    if (is_eqp(a, b))                    return false;
    unsigned wa = get_weight(a);
    unsigned wb = get_weight(b);
    if (wa < wb)                         return true;
    if (wa > wb)                         return false;
    if (a.kind() != b.kind())            return a.kind() < b.kind();
    if (use_hash) {
        if (a.hash() < b.hash())         return true;
        if (a.hash() > b.hash())         return false;
    }
    if (a == b)                          return false;
    switch (a.kind()) {
    case expr_kind::Var:
        return var_idx(a) < var_idx(b);
    case expr_kind::Constant:
        if (const_name(a) != const_name(b))
            return const_name(a) < const_name(b);
        else
            return is_lt(const_levels(a), const_levels(b), use_hash);
    case expr_kind::App:
        if (app_fn(a) != app_fn(b))
            return is_lt(app_fn(a), app_fn(b), use_hash);
        else
            return is_lt(app_arg(a), app_arg(b), use_hash);
    case expr_kind::Lambda: case expr_kind::Pi:
        if (binding_domain(a) != binding_domain(b))
            return is_lt(binding_domain(a), binding_domain(b), use_hash);
        else
            return is_lt(binding_body(a), binding_body(b), use_hash);
    case expr_kind::Let:
        if (let_type(a) != let_type(b))
            return is_lt(let_type(a), let_type(b), use_hash);
        else if (let_value(a) != let_value(b))
            return is_lt(let_value(a), let_value(b), use_hash);
        else
            return is_lt(let_body(a), let_body(b), use_hash);
    case expr_kind::Sort:
        return is_lt(sort_level(a), sort_level(b), use_hash);
    case expr_kind::Local: case expr_kind::Meta:
        if (mlocal_name(a) != mlocal_name(b))
            return mlocal_name(a) < mlocal_name(b);
        else
            return is_lt(mlocal_type(a), mlocal_type(b), use_hash);
    case expr_kind::Macro:
        if (macro_def(a) != macro_def(b))
            return macro_def(a) < macro_def(b);
        if (macro_num_args(a) != macro_num_args(b))
            return macro_num_args(a) < macro_num_args(b);
        for (unsigned i = 0; i < macro_num_args(a); i++) {
            if (macro_arg(a, i) != macro_arg(b, i))
                return is_lt(macro_arg(a, i), macro_arg(b, i), use_hash);
        }
        return false;
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Пример #2
0
 bool apply(expr const & a, expr const & b) {
     if (is_eqp(a, b))          return true;
     if (a.hash() != b.hash())  return false;
     if (a.kind() != b.kind())  return false;
     if (is_var(a))             return var_idx(a) == var_idx(b);
     if (m_cache.check(a, b))
         return true;
     switch (a.kind()) {
     case expr_kind::Var:
         lean_unreachable(); // LCOV_EXCL_LINE
     case expr_kind::Constant:
         return
             const_name(a) == const_name(b) &&
             compare(const_levels(a), const_levels(b), [](level const & l1, level const & l2) { return l1 == l2; });
     case expr_kind::Meta:
         return
             mlocal_name(a) == mlocal_name(b) &&
             apply(mlocal_type(a), mlocal_type(b));
     case expr_kind::Local:
         return
             mlocal_name(a) == mlocal_name(b) &&
             apply(mlocal_type(a), mlocal_type(b)) &&
             (!CompareBinderInfo || local_pp_name(a) == local_pp_name(b)) &&
             (!CompareBinderInfo || local_info(a) == local_info(b));
     case expr_kind::App:
         check_system();
         return
             apply(app_fn(a), app_fn(b)) &&
             apply(app_arg(a), app_arg(b));
     case expr_kind::Lambda: case expr_kind::Pi:
         check_system();
         return
             apply(binding_domain(a), binding_domain(b)) &&
             apply(binding_body(a), binding_body(b)) &&
             (!CompareBinderInfo || binding_name(a) == binding_name(b)) &&
             (!CompareBinderInfo || binding_info(a) == binding_info(b));
     case expr_kind::Let:
         check_system();
         return
             apply(let_type(a), let_type(b)) &&
             apply(let_value(a), let_value(b)) &&
             apply(let_body(a), let_body(b)) &&
             (!CompareBinderInfo || let_name(a) == let_name(b));
     case expr_kind::Sort:
         return sort_level(a) == sort_level(b);
     case expr_kind::Macro:
         check_system();
         if (macro_def(a) != macro_def(b) || macro_num_args(a) != macro_num_args(b))
             return false;
         for (unsigned i = 0; i < macro_num_args(a); i++) {
             if (!apply(macro_arg(a, i), macro_arg(b, i)))
                 return false;
         }
         return true;
     }
     lean_unreachable(); // LCOV_EXCL_LINE
 }
Пример #3
0
bool expr_eq_fn::apply(expr const & a, expr const & b) {
    if (is_eqp(a, b))          return true;
    if (a.hash() != b.hash())  return false;
    if (a.kind() != b.kind())  return false;
    if (is_var(a))             return var_idx(a) == var_idx(b);
    if (m_counter >= LEAN_EQ_CACHE_THRESHOLD && is_shared(a) && is_shared(b)) {
        auto p = std::make_pair(a.raw(), b.raw());
        if (!m_eq_visited)
            m_eq_visited.reset(new expr_cell_pair_set);
        if (m_eq_visited->find(p) != m_eq_visited->end())
            return true;
        m_eq_visited->insert(p);
    }
    check_system("expression equality test");
    switch (a.kind()) {
    case expr_kind::Var:
        lean_unreachable(); // LCOV_EXCL_LINE
    case expr_kind::Constant:
        return
            const_name(a) == const_name(b) &&
            compare(const_levels(a), const_levels(b), [](level const & l1, level const & l2) { return l1 == l2; });
    case expr_kind::Local: case expr_kind::Meta:
        return
            mlocal_name(a) == mlocal_name(b) &&
            apply(mlocal_type(a), mlocal_type(b));
    case expr_kind::App:
        m_counter++;
        return
            apply(app_fn(a), app_fn(b)) &&
            apply(app_arg(a), app_arg(b));
    case expr_kind::Lambda: case expr_kind::Pi:
        m_counter++;
        return
            apply(binding_domain(a), binding_domain(b)) &&
            apply(binding_body(a), binding_body(b)) &&
            (!m_compare_binder_info || binding_info(a) == binding_info(b));
    case expr_kind::Sort:
        return sort_level(a) == sort_level(b);
    case expr_kind::Macro:
        m_counter++;
        if (macro_def(a) != macro_def(b) || macro_num_args(a) != macro_num_args(b))
            return false;
        for (unsigned i = 0; i < macro_num_args(a); i++) {
            if (!apply(macro_arg(a, i), macro_arg(b, i)))
                return false;
        }
        return true;
    case expr_kind::Let:
        m_counter++;
        return
            apply(let_type(a), let_type(b)) &&
            apply(let_value(a), let_value(b)) &&
            apply(let_body(a), let_body(b));
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Пример #4
0
bool is_lt_no_level_params(expr const & a, expr const & b) {
    if (is_eqp(a, b))                    return false;
    unsigned wa = get_weight(a);
    unsigned wb = get_weight(b);
    if (wa < wb)                         return true;
    if (wa > wb)                         return false;
    if (a.kind() != b.kind())            return a.kind() < b.kind();
    switch (a.kind()) {
    case expr_kind::Var:
        return var_idx(a) < var_idx(b);
    case expr_kind::Constant:
        if (const_name(a) != const_name(b))
            return const_name(a) < const_name(b);
        else
            return is_lt_no_level_params(const_levels(a), const_levels(b));
    case expr_kind::App:
        if (is_lt_no_level_params(app_fn(a), app_fn(b)))
            return true;
        else if (is_lt_no_level_params(app_fn(b), app_fn(a)))
            return false;
        else
            return is_lt_no_level_params(app_arg(a), app_arg(b));
    case expr_kind::Lambda: case expr_kind::Pi:
        if (is_lt_no_level_params(binding_domain(a), binding_domain(b)))
            return true;
        else if (is_lt_no_level_params(binding_domain(b), binding_domain(a)))
            return false;
        else
            return is_lt_no_level_params(binding_body(a), binding_body(b));
    case expr_kind::Sort:
        return is_lt_no_level_params(sort_level(a), sort_level(b));
    case expr_kind::Local: case expr_kind::Meta:
        if (mlocal_name(a) != mlocal_name(b))
            return mlocal_name(a) < mlocal_name(b);
        else
            return is_lt_no_level_params(mlocal_type(a), mlocal_type(b));
    case expr_kind::Macro:
        if (macro_def(a) != macro_def(b))
            return macro_def(a) < macro_def(b);
        if (macro_num_args(a) != macro_num_args(b))
            return macro_num_args(a) < macro_num_args(b);
        for (unsigned i = 0; i < macro_num_args(a); i++) {
            if (is_lt_no_level_params(macro_arg(a, i), macro_arg(b, i)))
                return true;
            else if (is_lt_no_level_params(macro_arg(b, i), macro_arg(a, i)))
                return false;
        }
        return false;
    }
    lean_unreachable();
}
  void PrescribedMoleFractionsDirichletOldStyleBCFactory::
  convert_mole_fracs_and_add_to_func
  (const GetPot& input, const std::vector<libMesh::Number>& species_mole_fracs,
   const SpeciesMassFractionsVariable& species_fe_var,
   libMesh::CompositeFunction<libMesh::Number>& composite_func) const
  {
    const std::string& material = species_fe_var.material();

    /*! \todo We should have a ChemsitryWarehouse or something to just
      grab this from one place instead of rebuilding. */
    ChemistryBuilder chem_builder;
    std::unique_ptr<ChemistryType> chem_ptr;
    chem_builder.build_chemistry(input,material,chem_ptr);

    const ChemistryType & chem = *chem_ptr;

    const unsigned int n_vars = species_mole_fracs.size();
    // Compute M
    libMesh::Real M = 0.0;
    for( unsigned int s = 0; s < n_vars; s++ )
      M += species_mole_fracs[s]*chem.M(s);

    // Convert mole fractions to mass fractions and add to function
    for( unsigned int s = 0; s < n_vars; s++ )
      {
        libMesh::Number species_mass_fracs =species_mole_fracs[s]*chem.M(s)/M;

        std::vector<VariableIndex> var_idx(1,species_fe_var.species(s));

        libMesh::ConstFunction<libMesh::Number> const_func(species_mass_fracs);
        composite_func.attach_subfunction(const_func,var_idx);
      }
  }
  void DisplacementContinuationSolver::increment_displacement( GRINS::MultiphysicsSystem& system,
                                                               libMesh::EquationSystems& equation_system,
                                                               const libMesh::Real displacement )
  {
    // Get DirichetBoundaries vector.
    libMesh::DirichletBoundaries* d_vector = system.get_dof_map().get_dirichlet_boundaries();

    // Get the DirichletBoundary we want
    libMesh::DirichletBoundary* dirichlet = (*d_vector)[_bc_index];

    // Kill the old FunctionBase object and put in our new one.
    libMesh::FunctionBase<libMesh::Real>* composite_func_ptr = new libMesh::CompositeFunction<libMesh::Real>;
    libMesh::CompositeFunction<libMesh::Real>& composite_func = libMesh::cast_ref<libMesh::CompositeFunction<libMesh::Real>&>( *composite_func_ptr );

    std::vector<VariableIndex> var_idx(1,0); // Hardcoding to Ux displacement component
    composite_func.attach_subfunction( libMesh::ConstFunction<libMesh::Real>(displacement), var_idx );

    // DirichletBoundary now takes ownership of the pointer
    dirichlet->f.reset(composite_func_ptr);

    // Need to reinit system
    equation_system.reinit();

    return;
  }
Пример #7
0
expr copy(expr const & a) {
    switch (a.kind()) {
    case expr_kind::Var:      return mk_var(var_idx(a));
    case expr_kind::Constant: return mk_constant(const_name(a));
    case expr_kind::Type:     return mk_type(ty_level(a));
    case expr_kind::Value:    return mk_value(static_cast<expr_value*>(a.raw())->m_val);
    case expr_kind::App:      return mk_app(num_args(a), begin_args(a));
    case expr_kind::Eq:       return mk_eq(eq_lhs(a), eq_rhs(a));
    case expr_kind::Lambda:   return mk_lambda(abst_name(a), abst_domain(a), abst_body(a));
    case expr_kind::Pi:       return mk_pi(abst_name(a), abst_domain(a), abst_body(a));
    case expr_kind::Let:      return mk_let(let_name(a), let_type(a), let_value(a), let_body(a));
    case expr_kind::MetaVar:  return mk_metavar(metavar_idx(a), metavar_ctx(a));
    }
    lean_unreachable();
}
Пример #8
0
/** \brief Given \c a, an expression that is the denotation of an expression, if \c a is a variable,
    then use the actions in the transitions \c ts to expand \c a. The idea is to produce a head symbol
    we can use to decide whether the notation should be considered during pretty printing.

    \see get_head_index
*/
static expr expand_pp_pattern(unsigned num, transition const * ts, expr const & a) {
    lean_assert(is_simple(num, ts));
    if (!is_var(a))
        return a;
    return replace(a, [&](expr const & e) {
            if (is_var(e)) {
                unsigned vidx = var_idx(e);
                unsigned i = num;
                unsigned offset = 0;
                while (i > 0) {
                    --i;
                    action const & act = ts[i].get_action();
                    switch (act.kind()) {
                    case action_kind::Binder: case action_kind::Binders: case action_kind::Skip:
                        break;
                    case action_kind::Ext: case action_kind::LuaExt:
                        lean_unreachable();
                    case action_kind::Expr:
                        if (vidx == 0) return none_expr();
                        offset++;
                        vidx--;
                        break;
                    case action_kind::Exprs:
                        if (vidx == 0)
                            return some_expr(lift_free_vars(act.get_rec(), offset));
                        offset++;
                        vidx--;
                        break;
                    case action_kind::ScopedExpr:
                        if (vidx == 0)
                            return some_expr(lift_free_vars(act.get_rec(), offset));
                        offset++;
                        vidx--;
                        break;
                    }
                }
                return none_expr();
            } else {
                return none_expr();
            }
        });
}
Пример #9
0
  void ConstantFunctionDirichletBCFactory::add_found_vars( const GetPot& input,
                                                           MultiphysicsSystem& system,
                                                           const std::string& section,
                                                           const std::set<std::string>& vars_found,
                                                           libMesh::CompositeFunction<libMesh::Number>& composite_func,
                                                           std::set<std::string>& vars_added ) const
  {
    libMesh::Number invalid_num = std::numeric_limits<libMesh::Number>::max();

    for( std::set<std::string>::const_iterator var = vars_found.begin();
         var != vars_found.end(); ++var )
      {
        std::vector<VariableIndex> var_idx(1,system.variable_number(*var));

        libMesh::Number value = input(section+"/"+(*var),invalid_num);

        libMesh::ConstFunction<libMesh::Number> const_func(value);
        composite_func.attach_subfunction(const_func,var_idx);
      }

    vars_added = vars_found;
  }
Пример #10
0
 /* Return true iff v is of the form (g y_1 ... y_n) where
    y_i is a constant or a variable.
    Moreover, y_i's variables are pairwise distinct. */
 bool is_simple_application(expr const & v) {
     buffer<expr> ys;
     buffer<bool> bitmap;
     expr const & g = get_app_args(v, ys);
     if (!is_constant(g) && !is_var(g))
         return false;
     for (expr const & y : ys) {
         if (!is_var(y) && !is_constant(y))
             return false;
         if (is_var(y)) {
             unsigned vidx = var_idx(y);
             if (vidx >= bitmap.size())
                 bitmap.resize(vidx+1, false);
             if (bitmap[vidx]) {
                 /* y_i's are not pairwise distinct */
                 return false;
             }
             bitmap[vidx] = true;
         }
     }
     return true;
 }
Пример #11
0
static bool is_permutation(expr const & lhs, expr const & rhs, unsigned offset, buffer<optional<unsigned>> & p) {
    if (lhs.kind() != rhs.kind())
        return false;
    switch (lhs.kind()) {
    case expr_kind::Constant: case expr_kind::Sort:
    case expr_kind::Meta: case expr_kind::Local:
        return lhs == rhs;
    case expr_kind::Var:
        if (var_idx(lhs) < offset) {
            return lhs == rhs; // locally bound variable
        } else if (var_idx(lhs) - offset < p.size()) {
            if (p[var_idx(lhs) - offset]) {
                return *(p[var_idx(lhs) - offset]) == var_idx(rhs);
            } else {
                p[var_idx(lhs) - offset] = var_idx(rhs);
                return true;
            }
        } else {
            return lhs == rhs; // free variable
        }
    case expr_kind::Lambda: case expr_kind::Pi:
        return
            is_permutation(binding_domain(lhs), binding_domain(rhs), offset, p) &&
            is_permutation(binding_body(lhs), binding_body(rhs), offset+1, p);
    case expr_kind::App:
        return
            is_permutation(app_fn(lhs), app_fn(rhs), offset, p) &&
            is_permutation(app_arg(lhs), app_arg(rhs), offset, p);
    case expr_kind::Macro:
        if (macro_def(lhs) != macro_def(rhs) ||
            macro_num_args(lhs) != macro_num_args(rhs))
            return false;
        for (unsigned i = 0; i < macro_num_args(lhs); i++) {
            if (!is_permutation(macro_arg(lhs, i), macro_arg(rhs, i), offset, p))
                return false;
        }
        return true;
    }
    lean_unreachable();
}
Пример #12
0
bool light_lt_manager::is_lt(expr const & a, expr const & b) {
    if (is_eqp(a, b)) return false;
    unsigned wa = get_weight(a);
    unsigned wb = get_weight(b);
    if (wa < wb)                         return true;
    if (wa > wb)                         return false;
    if (is_constant(get_app_fn(a))) {
        unsigned const * light_arg = m_lrs.find(const_name(get_app_fn(a)));
        if (light_arg) {
            buffer<expr> args;
            get_app_args(a, args);
            if (args.size() > *light_arg) return is_lt(args[*light_arg], b);
        }
    }
    if (is_constant(get_app_fn(b))) {
        unsigned const * light_arg = m_lrs.find(const_name(get_app_fn(b)));
        if (light_arg) {
            buffer<expr> args;
            get_app_args(b, args);
            if (args.size() > *light_arg) return !is_lt(args[*light_arg], a);
        }
    }
    if (a.kind() != b.kind())            return a.kind() < b.kind();
    if (a == b)                          return false;
    switch (a.kind()) {
    case expr_kind::Var:
        return var_idx(a) < var_idx(b);
    case expr_kind::Constant:
        if (const_name(a) != const_name(b))
            return const_name(a) < const_name(b);
        else
            return ::lean::is_lt(const_levels(a), const_levels(b), false);
    case expr_kind::App:
        if (app_fn(a) != app_fn(b))
            return is_lt(app_fn(a), app_fn(b));
        else
            return is_lt(app_arg(a), app_arg(b));
    case expr_kind::Lambda: case expr_kind::Pi:
        if (binding_domain(a) != binding_domain(b))
            return is_lt(binding_domain(a), binding_domain(b));
        else
            return is_lt(binding_body(a), binding_body(b));
    case expr_kind::Sort:
        return ::lean::is_lt(sort_level(a), sort_level(b), false);
    case expr_kind::Local: case expr_kind::Meta:
        if (mlocal_name(a) != mlocal_name(b))
            return mlocal_name(a) < mlocal_name(b);
        else
            return is_lt(mlocal_type(a), mlocal_type(b));
    case expr_kind::Macro:
        if (macro_def(a) != macro_def(b))
            return macro_def(a) < macro_def(b);
        if (macro_num_args(a) != macro_num_args(b))
            return macro_num_args(a) < macro_num_args(b);
        for (unsigned i = 0; i < macro_num_args(a); i++) {
            if (macro_arg(a, i) != macro_arg(b, i))
                return is_lt(macro_arg(a, i), macro_arg(b, i));
        }
        return false;
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Пример #13
0
bool abstract_expr_manager::is_equal(expr const & a, expr const & b) {
    if (is_eqp(a, b))          return true;
    if (a.kind() != b.kind())  return false;
    if (is_var(a))             return var_idx(a) == var_idx(b);
    bool is_eq;
    switch (a.kind()) {
    case expr_kind::Var:
        lean_unreachable(); // LCOV_EXCL_LINE
    case expr_kind::Constant: case expr_kind::Sort:
        return a == b;
    case expr_kind::Meta: case expr_kind::Local:
        return mlocal_name(a) == mlocal_name(b) && is_equal(mlocal_type(a), mlocal_type(b));
    case expr_kind::Lambda: case expr_kind::Pi:
        if (!is_equal(binding_domain(a), binding_domain(b))) return false;
        // see comment at abstract_expr_manager::hash
        m_locals.push_back(instantiate_rev(m_tctx.mk_tmp_local(binding_domain(a)), m_locals.size(), m_locals.data()));
        is_eq = is_equal(binding_body(a), binding_body(b));
        m_locals.pop_back();
        return is_eq;
    case expr_kind::Macro:
        if (macro_def(a) != macro_def(b) || macro_num_args(a) != macro_num_args(b))
            return false;
        for (unsigned i = 0; i < macro_num_args(a); i++) {
            if (!is_equal(macro_arg(a, i), macro_arg(b, i)))
                return false;
        }
        return true;
    case expr_kind::App:
        buffer<expr> a_args, b_args;
        expr const & f_a   = get_app_args(a, a_args);
        expr const & f_b   = get_app_args(b, b_args);
        if (!is_equal(f_a, f_b))
            return false;
        if (a_args.size() != b_args.size())
            return false;
        unsigned prefix_sz = m_congr_lemma_manager.get_specialization_prefix_size(instantiate_rev(f_a, m_locals.size(), m_locals.data()), a_args.size());
        for (unsigned i = 0; i < prefix_sz; i++) {
            if (!is_equal(a_args[i], b_args[i]))
                return false;
        }
        expr new_f_a       = a;
        unsigned rest_sz   = a_args.size() - prefix_sz;
        for (unsigned i = 0; i < rest_sz; i++) {
            new_f_a = app_fn(new_f_a);
        }
        new_f_a = instantiate_rev(new_f_a, m_locals.size(), m_locals.data());
        optional<congr_lemma> congr = m_congr_lemma_manager.mk_congr(new_f_a, rest_sz);
        bool not_equal = false;
        if (!congr) {
            for (unsigned i = prefix_sz; i < a_args.size(); ++i) {
                if (!is_equal(a_args[i], b_args[i])) {
                    not_equal = true;
                    break;
                }
            }
        } else {
            lean_assert(length(congr->get_arg_kinds()) == rest_sz);
            unsigned i = prefix_sz;
            for_each(congr->get_arg_kinds(), [&](congr_arg_kind const & c_kind) {
                    if (not_equal)
                        return;
                    if (c_kind != congr_arg_kind::Cast && !is_equal(a_args[i], b_args[i])) {
                        not_equal = true;
                    }
                    i++;
                });
        }
        return !not_equal;
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Пример #14
0
bool is_lt(expr const & a, expr const & b, bool use_hash) {
    if (is_eqp(a, b))                    return false;
    unsigned da = get_depth(a);
    unsigned db = get_depth(b);
    if (da < db)                         return true;
    if (da > db)                         return false;
    if (a.kind() != b.kind())            return a.kind() < b.kind();
    if (use_hash) {
        if (a.hash() < b.hash())         return true;
        if (a.hash() > b.hash())         return false;
    }
    if (a == b)                          return false;
    if (is_var(a))                       return var_idx(a) < var_idx(b);
    switch (a.kind()) {
    case expr_kind::Var:
        lean_unreachable(); // LCOV_EXCL_LINE
    case expr_kind::Constant:
        return const_name(a) < const_name(b);
    case expr_kind::App:
        if (num_args(a) != num_args(b))
            return num_args(a) < num_args(b);
        for (unsigned i = 0; i < num_args(a); i++) {
            if (arg(a, i) != arg(b, i))
                return is_lt(arg(a, i), arg(b, i), use_hash);
        }
        lean_unreachable(); // LCOV_EXCL_LINE
    case expr_kind::Lambda:   // Remark: we ignore get_abs_name because we want alpha-equivalence
    case expr_kind::Pi:
        if (abst_domain(a) != abst_domain(b))
            return is_lt(abst_domain(a), abst_domain(b), use_hash);
        else
            return is_lt(abst_body(a), abst_body(b), use_hash);
    case expr_kind::Type:
        return ty_level(a) < ty_level(b);
    case expr_kind::Value:
        return to_value(a) < to_value(b);
    case expr_kind::Let:
        if (let_type(a) != let_type(b)) {
            return is_lt(let_type(a), let_type(b), use_hash);
        } else if (let_value(a) != let_value(b)){
            return is_lt(let_value(a), let_value(b), use_hash);
        } else {
            return is_lt(let_body(a), let_body(b), use_hash);
        }
    case expr_kind::MetaVar:
        if (metavar_name(a) != metavar_name(b)) {
            return metavar_name(a) < metavar_name(b);
        } else {
            auto it1  = metavar_lctx(a).begin();
            auto it2  = metavar_lctx(b).begin();
            auto end1 = metavar_lctx(a).end();
            auto end2 = metavar_lctx(b).end();
            for (; it1 != end1 && it2 != end2; ++it1, ++it2) {
                if (it1->kind() != it2->kind()) {
                    return it1->kind() < it2->kind();
                } else if (it1->s() != it2->s()) {
                    return it1->s() < it2->s();
                } else if (it1->is_inst()) {
                    if (it1->v() != it2->v())
                        return is_lt(it1->v(), it2->v(), use_hash);
                } else {
                    if (it1->n() != it2->n())
                        return it1->n() < it2->n();
                }
            }
            return it1 == end1 && it2 != end2;
        }
    }
    lean_unreachable(); // LCOV_EXCL_LINE
}
Пример #15
0
  void MoleFractionsDirichletBCFactory::add_mole_frac_to_mass_frac(const GetPot& input,
                                                                   const std::string& section,
                                                                   const std::set<std::string>& vars_found,
                                                                   const std::string& material,
                                                                   const SpeciesMassFractionsVariable& species_fe_var,
                                                                   libMesh::CompositeFunction<libMesh::Number>& composite_func,
                                                                   std::set<std::string>& vars_added) const
  {
    unsigned int n_vars_found = vars_found.size();

    // Parse in all the species mole fracs that are in the input (it is assumed non-specified are 0)
    std::vector<libMesh::Number> species_mole_fracs(n_vars_found);
    libMesh::Number invalid_num = std::numeric_limits<libMesh::Number>::max();
    {
      unsigned int count = 0;
      for(std::set<std::string>::const_iterator var = vars_found.begin();
          var != vars_found.end(); ++var )
        {
          species_mole_fracs[count] = input(section+"/"+(*var),invalid_num);
          count++;
        }
    }

    // Make sure mole fracs sum to 1
    libMesh::Number sum = 0.0;
    for(unsigned int v = 0; v < n_vars_found; v++ )
      sum += species_mole_fracs[v];

    libMesh::Number tol = std::numeric_limits<libMesh::Number>::epsilon()*10;
    if( std::abs(sum-1.0) > tol )
      libmesh_error_msg("ERROR: Mole fractions do not sum to 1! Found sum = "+StringUtilities::T_to_string<libMesh::Number>(sum));

    // Extract species names
    std::vector<std::string> species_names(n_vars_found);
    {
      unsigned int count = 0;
      for(std::set<std::string>::const_iterator var = vars_found.begin();
          var != vars_found.end(); ++var )
        {
          std::vector<std::string> split_name;
          // vars_found should have the form "X_<species name>"
          StringUtilities::split_string((*var),"_",split_name);
          libmesh_assert_equal_to(split_name[0],std::string("X"));
          libmesh_assert_equal_to(split_name.size(),2);
          species_names[count] = split_name[1];
          count++;
        }
    }

    // Now convert to mass frac and add to composite function
    /*! \todo We should have a ChemsitryWarehouse or something to just grab this from one place
      instead of rebuilding. */
    ChemistryType chem(input,material);

    libMesh::Real M = 0.0;
    for(unsigned int v = 0; v < n_vars_found; v++ )
      {
        unsigned int s = chem.species_index(species_names[v]);
        M += species_mole_fracs[v]*chem.M(s);
      }

    const std::string& prefix = species_fe_var.prefix();

    for(unsigned int v = 0; v < n_vars_found; v++ )
      {
        // Finish computing species mass fraction
        unsigned int s = chem.species_index(species_names[v]);
        libMesh::Number species_mass_fracs = species_mole_fracs[v]*chem.M(s)/M;

        // Add the function
        std::vector<VariableIndex> var_idx(1,species_fe_var.species(s));
        libMesh::ConstFunction<libMesh::Number> const_func(species_mass_fracs);
        composite_func.attach_subfunction(const_func,var_idx);

        // Log that we added this variable
        vars_added.insert(prefix+species_names[v]);
      }
  }