Esempio n. 1
0
		AngularMatrix::AngularMatrix(const gmtl::Vec3f& center, const float& range, uint32_t size)
		{
			this->center = center;
			this->range = range;
			this->size = size;
	
			matrix.resize(boost::extents[size][size][size][3]);
	
			minimum[0] = center[0]-(range/2.0f);
			minimum[1] = center[1]-(range/2.0f);
			minimum[2] = center[2]-(range/2.0f);

			maximum[0] = center[0]+(range/2.0f);
			maximum[1] = center[1]+(range/2.0f);
			maximum[2] = center[2]+(range/2.0f);
	
			delta = range/size;
	
			minimumPosition[0] = .100;
			minimumPosition[1] = .100;
			minimumPosition[2] = .250;

			maximumPosition[0] = -.100;
			maximumPosition[1] = -.100;
			maximumPosition[2] = 0.050;

			gmtl::Vec3f zero_vec(0,0,0);
			
			for (uint32_t i=0; i<size; i++)
				for (uint32_t j=0; j<size; j++)
					for (uint32_t k=0; k<size; k++)
					{
						setVec(i,j,k,zero_vec);
					}
		}
Esempio n. 2
0
RealVectorValue
CrackFrontDefinition::calculateCrackFrontDirection(const Node* crack_front_node,
                                                   const RealVectorValue& tangent_direction,
                                                   const CRACK_NODE_TYPE ntype) const
{
  RealVectorValue crack_dir;
  RealVectorValue zero_vec(0.0);

  bool calc_dir = true;
  if (_end_direction_method == END_CRACK_DIRECTION_VECTOR)
  {
    if (ntype == END_1_NODE)
    {
      crack_dir = _crack_direction_vector_end_1;
      calc_dir = false;
    }
    else if (ntype == END_2_NODE)
    {
      crack_dir = _crack_direction_vector_end_2;
      calc_dir = false;
    }
  }

  if (calc_dir)
  {
    if (_direction_method == CRACK_DIRECTION_VECTOR)
    {
      crack_dir = _crack_direction_vector;
    }
    else if (_direction_method == CRACK_MOUTH)
    {
      if (_crack_mouth_coordinates.absolute_fuzzy_equals(*crack_front_node,1.e-15))
      {
        mooseError("Crack mouth too close to crack front node");
      }
      RealVectorValue mouth_to_front = *crack_front_node - _crack_mouth_coordinates;

      RealVectorValue crack_plane_normal = mouth_to_front.cross(tangent_direction);
      if (crack_plane_normal.absolute_fuzzy_equals(zero_vec,1.e-15))
      {
        mooseError("Vector from crack mouth to crack front node is collinear with crack front segment");
      }

      crack_dir = tangent_direction.cross(crack_plane_normal);
      Real dotprod = crack_dir*mouth_to_front;
      if (dotprod < 0)
      {
        crack_dir = -crack_dir;
      }
    }
    else if (_direction_method == CURVED_CRACK_FRONT)
    {
      crack_dir = tangent_direction.cross(_crack_plane_normal);
    }
  }
  crack_dir = crack_dir.unit();

  return crack_dir;
}
Esempio n. 3
0
Vec vec_copy(Vec v1)
{
   Vec vec;

   vec = zero_vec();
   vec->x = v1->x; vec->y = v1->y; vec->z = v1->z;
   return vec;
}
Esempio n. 4
0
Vec new_vec(double X, double Y, double Z)
{
   Vec vec;

   vec = zero_vec();
   vec->x = X; vec->y = Y; vec->z = Z;
   return vec;
}
Esempio n. 5
0
 Eigen::VectorXd Shrinkage
 (
   const Eigen::VectorXd& vec, const double kappa
 ) const
 {
   Eigen::ArrayXd zero_vec(vec.size());
   zero_vec.setZero();
   return zero_vec.max( vec.array() - kappa) -
          zero_vec.max(-vec.array() - kappa);
 }
Esempio n. 6
0
void
CrackFrontDefinition::updateDataForCrackDirection()
{
  if (_direction_method == CRACK_MOUTH)
  {
    _crack_mouth_coordinates.zero();

    std::set<Node*> crack_mouth_nodes;
    ConstBndNodeRange & bnd_nodes = *_mesh.getBoundaryNodeRange();
    for (ConstBndNodeRange::const_iterator nd = bnd_nodes.begin() ; nd != bnd_nodes.end(); ++nd)
    {
      const BndNode * bnode = *nd;
      BoundaryID boundary_id = bnode->_bnd_id;

      for (unsigned int ibid=0; ibid<_crack_mouth_boundary_ids.size(); ++ibid)
      {
        if (boundary_id == _crack_mouth_boundary_ids[ibid])
        {
          crack_mouth_nodes.insert(bnode->_node);
          break;
        }
      }
    }

    for (std::set<Node*>::iterator nit=crack_mouth_nodes.begin();
         nit != crack_mouth_nodes.end();
         ++nit)
    {
      _crack_mouth_coordinates += **nit;
    }
    _crack_mouth_coordinates /= (Real)crack_mouth_nodes.size();
  }
  else if (_direction_method == CURVED_CRACK_FRONT)
  {
    _crack_plane_normal.zero();

    //Get 3 nodes on crack front
    unsigned int num_nodes(_ordered_crack_front_nodes.size());
    if (num_nodes<3)
    {
      mooseError("Crack front must contain at least 3 nodes to use CurvedCrackFront option");
    }
    unsigned int mid_id = (num_nodes-1)/2;
    Node & start = _mesh.node(_ordered_crack_front_nodes[0]);
    Node & mid   = _mesh.node(_ordered_crack_front_nodes[mid_id]);
    Node & end   = _mesh.node(_ordered_crack_front_nodes[num_nodes-1]);

    //Create two vectors connecting them
    RealVectorValue v1 = mid-start;
    RealVectorValue v2 = end-mid;

    //Take cross product to get normal
    _crack_plane_normal = v1.cross(v2);
    _crack_plane_normal = _crack_plane_normal.unit();

    //Make sure they're not collinear
    RealVectorValue zero_vec(0.0);
    if (_crack_plane_normal.absolute_fuzzy_equals(zero_vec,1.e-15))
    {
      mooseError("Nodes on crack front are too close to being collinear");
    }
  }
}
Esempio n. 7
0
void
CrackFrontDefinition::updateCrackFrontGeometry()
{
  updateDataForCrackDirection();

  _segment_lengths.clear();
  _tangent_directions.clear();
  _crack_directions.clear();
  _rot_matrix.clear();

  if (_treat_as_2d)
  {
    RealVectorValue tangent_direction;
    RealVectorValue crack_direction;
    tangent_direction(_axis_2d) = 1.0;
    _tangent_directions.push_back(tangent_direction);
    const Node* crack_front_node = _mesh.nodePtr(_ordered_crack_front_nodes[0]);
    crack_direction = calculateCrackFrontDirection(crack_front_node,tangent_direction,MIDDLE_NODE);
    _crack_directions.push_back(crack_direction);
    _crack_plane_normal = crack_direction.cross(tangent_direction);
    ColumnMajorMatrix rot_mat;
    rot_mat(0,0) = crack_direction(0);
    rot_mat(0,1) = crack_direction(1);
    rot_mat(0,2) = crack_direction(2);
    rot_mat(1,0) = _crack_plane_normal(0);
    rot_mat(1,1) = _crack_plane_normal(1);
    rot_mat(1,2) = _crack_plane_normal(2);
    rot_mat(2,0) = 0.0;
    rot_mat(2,1) = 0.0;
    rot_mat(2,2) = 0.0;
    rot_mat(2,_axis_2d) = 1.0;
    _rot_matrix.push_back(rot_mat);

    _segment_lengths.push_back(std::make_pair(0.0,0.0));
    _overall_length = 0.0;
  }
  else
  {
    unsigned int num_crack_front_nodes = _ordered_crack_front_nodes.size();
    std::vector<Node*> crack_front_nodes;
    crack_front_nodes.reserve(num_crack_front_nodes);
    _segment_lengths.reserve(num_crack_front_nodes);
    _tangent_directions.reserve(num_crack_front_nodes);
    _crack_directions.reserve(num_crack_front_nodes);
    for (unsigned int i=0; i<num_crack_front_nodes; ++i)
    {
      crack_front_nodes.push_back(_mesh.nodePtr(_ordered_crack_front_nodes[i]));
    }

    _overall_length = 0.0;

    RealVectorValue back_segment;
    Real back_segment_len = 0.0;
    for (unsigned int i=0; i<num_crack_front_nodes; ++i)
    {
      CRACK_NODE_TYPE ntype = MIDDLE_NODE;
      if (i==0)
      {
        ntype = END_1_NODE;
      }
      else if (i==num_crack_front_nodes-1)
      {
        ntype = END_2_NODE;
      }

      RealVectorValue forward_segment;
      Real forward_segment_len = 0.0;
      if (ntype != END_2_NODE)
      {
        forward_segment = *crack_front_nodes[i+1] - *crack_front_nodes[i];
        forward_segment_len = forward_segment.size();
      }

      _segment_lengths.push_back(std::make_pair(back_segment_len,forward_segment_len));
      //Moose::out<<"seg len: "<<back_segment_len<<" "<<forward_segment_len<<std::endl;

      RealVectorValue tangent_direction = back_segment + forward_segment;
      tangent_direction = tangent_direction / tangent_direction.size();
      _tangent_directions.push_back(tangent_direction);
      //Moose::out<<"tan dir: "<<tangent_direction(0)<<" "<<tangent_direction(1)<<" "<<tangent_direction(2)<<std::endl;
      _crack_directions.push_back(calculateCrackFrontDirection(crack_front_nodes[i],tangent_direction,ntype));

      _overall_length += forward_segment_len;

      back_segment = forward_segment;
      back_segment_len = forward_segment_len;

    }

    //For CURVED_CRACK_FRONT, _crack_plane_normal gets computed in updateDataForCrackDirection
    if (_direction_method != CURVED_CRACK_FRONT)
    {
      unsigned int mid_id = (num_crack_front_nodes-1)/2;
      _crack_plane_normal = _tangent_directions[mid_id].cross(_crack_directions[mid_id]);

      //Make sure the normal vector is non-zero
      RealVectorValue zero_vec(0.0);
      if (_crack_plane_normal.absolute_fuzzy_equals(zero_vec,1.e-15))
        mooseError("Crack plane normal vector evaluates to zero");
    }

    // Create rotation matrix
    for (unsigned int i=0; i<num_crack_front_nodes; ++i)
    {
      ColumnMajorMatrix rot_mat;
      rot_mat(0,0) = _crack_directions[i](0);
      rot_mat(0,1) = _crack_directions[i](1);
      rot_mat(0,2) = _crack_directions[i](2);
      rot_mat(1,0) = _crack_plane_normal(0);
      rot_mat(1,1) = _crack_plane_normal(1);
      rot_mat(1,2) = _crack_plane_normal(2);
      rot_mat(2,0) = _tangent_directions[i](0);
      rot_mat(2,1) = _tangent_directions[i](1);
      rot_mat(2,2) = _tangent_directions[i](2);
      _rot_matrix.push_back(rot_mat);
    }

    Moose::out<<"Summary of J-Integral crack front geometry:"<<std::endl;
    Moose::out<<"index   node id   x coord       y coord       z coord       x dir         y dir          z dir        seg length"<<std::endl;
    for (unsigned int i=0; i<crack_front_nodes.size(); ++i)
    {
      Moose::out<<std::left
                <<std::setw(8) <<i+1
                <<std::setw(10)<<crack_front_nodes[i]->id()
                <<std::setw(14)<<(*crack_front_nodes[i])(0)
                <<std::setw(14)<<(*crack_front_nodes[i])(1)
                <<std::setw(14)<<(*crack_front_nodes[i])(2)
                <<std::setw(14)<<_crack_directions[i](0)
                <<std::setw(14)<<_crack_directions[i](1)
                <<std::setw(14)<<_crack_directions[i](2)
                <<std::setw(14)<<(_segment_lengths[i].first+_segment_lengths[i].second)/2.0
                <<std::endl;
    }
    Moose::out<<"overall length: "<<_overall_length<<std::endl;
  }
}
/*
 * Extend mondrian block to include new training data
 */
void MondrianNode::extend_mondrian_block(const Sample& sample) {
    if (settings_->debug)
        cout << "### extend_mondrian_block: " << endl;

    float split_cost = 0.; /* On split_cost depends 
                             if a new split is introduced */
    /* 
     * Set new lower and upper boundary:
     *  - e_lower = max(l^x_j - x,0)
     *  - e_upper = min(x - u^x_j,0)
     */
    arma::fvec zero_vec(mondrian_block_->get_feature_dim(), arma::fill::zeros);
    arma::fvec tmp_min_block = mondrian_block_->get_min_block_dim();
    arma::fvec tmp_max_block = mondrian_block_->get_max_block_dim();

    arma::fvec e_lower = arma::max(
            zero_vec, (tmp_min_block - sample.x));
    arma::fvec e_upper = arma::max(
            zero_vec, (sample.x - tmp_max_block));
    /*
     * sample e (expo_param) from exponential distribution with rate
     * sum_d( e^l_d + e^u_d )
     */
    float expo_param = arma::sum(e_lower) + arma::sum(e_upper);

    /* Exponential distribution */
    if (!greater_zero(expo_param)) {
        split_cost = numeric_limits<float>::infinity();
    } else {
        /* Exponential distribution */
        split_cost = random.rand_exp_distribution(expo_param);
    }

    /* Check if all labels are identical */
    if (pause_mondrian()) {
        /* Try to extend a paused Mondrian (labels are not identical) */
        assert(is_leaf_);
        split_cost = numeric_limits<float>::infinity();
    }

    /*
     * Check if current point lies
     *  (1) Current point lies within Mondrian Block B^x_j
     *  (2) Current point lies outside block B^x_j
     */
    if (equal(split_cost, max_split_costs_) == true || 
            split_cost > max_split_costs_) {
        /* (1) Current point lies within Mondrian Block B^x_j */
        if (!is_leaf_) {    
            mondrian_block_->update_range_states(sample.x); 
            add_training_point_to_node(sample);
            /* 
             * Check split dimension/location to choose left or right node
             * and recurse on child 
             */
            if (sample.x[split_dim_] <= split_loc_) {
                assert(id_left_child_node_!=NULL);
                id_left_child_node_->extend_mondrian_block(sample);
            } else {
                assert(id_right_child_node_!=NULL);
                id_right_child_node_->extend_mondrian_block(sample);
            }
        } else {
            assert(is_leaf_);
            if (!check_if_same_labels(sample)) {
                sample_mondrian_block(sample);
            }
            /* Update after calling function sample_mondrian_block,
             * because of new node would take new boundary properties */
            mondrian_block_->update_range_states(sample.x);
            add_training_point_to_node(sample);
        }
    } else {
        /* (2) Current point lies outside block B^x_j */
        /* Initialize new parent node */
        int feature_dim = mondrian_block_->get_feature_dim();
        arma::fvec min_block = arma::min(mondrian_block_->get_min_block_dim(), 
                sample.x);
        arma::fvec max_block = arma::max(mondrian_block_->get_max_block_dim(),
                sample.x);
        MondrianNode* new_parent_node = new MondrianNode(num_classes_,
                feature_dim, budget_, *id_parent_node_,
                min_block, max_block, *settings_, depth_);
        /* Set "new_parent_node" as new parent of current node */
        /* Pass histogram of current node to new parent node */
        new_parent_node->init_update_posterior_node_incremental(*this, sample);
        /* 
         * Sample split dimension \delta, choosing d with probability 
         * proportional to e^l_d + d^u_d
         */
        arma::fvec feat_score = e_lower + e_upper;
        /* Problem can occur that min and max boundary value are the same
         * at a sampled split location -> solution: sample again until
         * it is different */
        int split_dim = sample_multinomial_scores(feat_score);
        /* Check if it is possible to introduce a split in current dimension */
        int max_sample_search = mondrian_block_->get_feature_dim();
        int count_sample_search = 0;
        while (count_sample_search < max_sample_search) {
            if (equal(min_block[split_dim_], max_block[split_dim_])) {
                split_dim_ = sample_multinomial_scores(min_block);
            } else {
                break;
            }
            count_sample_search += 1;
        }   
        float split_loc = 0.0;  /* Split location */
        /*
         * Sample split location \xi uniformly from interval 
         * [u^x_{j,\delta},x_\delta] if x_\delta > u^x_{j,\delta}
         * [x_delta, l^x_{j,\delta}] else
         */
        if (sample.x[split_dim] > mondrian_block_->get_max_block_dim()
                [split_dim]) {
            split_loc = random.rand_uniform_distribution(
                    mondrian_block_->get_min_block_dim()[split_dim],
                    sample.x[split_dim]);
        } else {
            split_loc = random.rand_uniform_distribution(sample.x[split_dim], 
                    mondrian_block_->get_min_block_dim()[split_dim]);
        }
        float new_budget = budget_ - split_cost;
        /* 
         * Insert a new node (j~) just above node j in the tree,
         * and a new leaf'', sibling to j 
         */
        bool is_left_node = false;
        arma::fvec new_child_block(mondrian_block_->get_feature_dim());
        if (sample.x[split_dim] > split_loc) {
            is_left_node = true;
            new_child_block = max_block;
        } else {
            new_child_block = min_block;
        }
        /* Grow Mondrian child node of the "outer Mondrian" */
        int new_depth = depth_ +1;
        MondrianNode* child_node = new MondrianNode(num_classes_,
                feature_dim, new_budget, *new_parent_node,
                new_child_block, new_child_block, *settings_, new_depth);
        /* Set child nodes of new created parent node ("new_parent_node") */
        new_parent_node->set_child_node(*child_node, (!is_left_node));
        new_parent_node->set_child_node(*this, is_left_node);
        new_parent_node->is_leaf_ = false;
        /* Set "new_parent_node" as new child node of current parent node */
        if (id_parent_node_ != NULL ) { /* root node */
            if (id_parent_node_->id_left_child_node_ == this) {
                id_parent_node_->set_child_node(*new_parent_node, true);
            } else {
                id_parent_node_->set_child_node(*new_parent_node, false);
            }
        }
        /* Set "new_parent_node" as new parent of current node */
        id_parent_node_ = new_parent_node;
        /*
         * Initialize posterior of new created child node 
         * (initialize histogram with zeros -> pointer = NULL) 
         */
        MondrianNode* tmp_node = NULL;
        child_node->init_update_posterior_node_incremental(*tmp_node, sample);

        child_node->sample_mondrian_block(sample);

        budget_ = new_budget;
        /* Update split cost of current and new parent node */ 
        new_parent_node->max_split_costs_ = split_cost;
        new_parent_node->split_loc_ = split_loc;
        new_parent_node->split_dim_ = split_dim;
        max_split_costs_ -= split_cost;
        update_depth();
    }
     
}
/*
 * Predict class of current sample
 */
int MondrianNode::predict_class(Sample& sample, arma::fvec& pred_prob, 
        float& prob_not_separated_yet, mondrian_confidence& m_conf) {

    if (settings_->debug)
        cout << "predict_class..." << endl;
    int pred_class = -1;
    /* 
     * If x lies outside B^x_j at node j, the probability that x will branch 
     * off into its own node at node j, denoted by p^s_j(x), is equal to the
     * probability that a split exists in B_j outside B^x_j 
     */
    int feature_dimension = mondrian_block_->get_feature_dim();
    arma::fvec zero_vec(feature_dimension, arma::fill::zeros);
    /* \eta_j(x) */
    float expo_param = 1.0;
    expo_param = arma::accu(arma::max(zero_vec, 
                (sample.x - mondrian_block_->get_max_block_dim()))) + 
        arma::accu(arma::max(zero_vec, 
                    (mondrian_block_->get_min_block_dim() - sample.x)));
    /* Compute mondrian confidence values */
    if (is_leaf_) {
        /* 1. Compute euclidean distance */
        m_conf.distance = arma::norm(arma::max(zero_vec, 
                    (sample.x - mondrian_block_->get_max_block_dim())),2) + 
            arma::norm(arma::max(zero_vec, 
                        (mondrian_block_->get_min_block_dim() - sample.x)),2);
        /* 2. Get number of samples at current node */
        m_conf.number_of_points = arma::accu(id_parent_node_->count_labels_);
        /* 3. Calculate densitiy of current mondrian block */
        //arma::fvec tmp_vec = id_parent_node_->mondrian_block_->get_max_block_dim() - 
        //   id_parent_node_->mondrian_block_->get_min_block_dim();
        //arma::fvec tmp_vec = mondrian_block_->get_max_block_dim() - mondrian_block_->get_min_block_dim();
        m_conf.density = expo_param;
    }
    /* Probability that x_i will branch off into its own node at node j */
    float prob_not_separated_now = exp(-expo_param * max_split_costs_);
    float prob_separated_now = 1 - prob_not_separated_now;  /* p^s_j(x) */ 
    if (settings_->debug) {
        cout << "prob_not_separated_now: " << prob_not_separated_now << endl;
        cout << "prob_separated_now: " << prob_separated_now << endl;
    }
    arma::fvec base = get_prior_mean();
    
    float discount = exp(-settings_->discount_param * max_split_costs_);
    
    if (settings_->debug)
        cout << "discount: " << discount << endl;
    /* Interpolated Kneser Ney smoothing */
    arma::Col<arma::uword> cnt(*num_classes_, arma::fill::zeros);
    if (is_leaf_) {
        cnt = count_labels_;
    } else {
        arma::Col<arma::uword> ones_vec(*num_classes_, arma::fill::ones);
        cnt = arma::min(count_labels_, ones_vec);
    }

    /* Check if current sample lies outside */
    // or expo_param > 0
    if (greater_zero(expo_param)) {
        /* 
         * Compute expected discount d, where \delta is drawn from a truncated
         * expoential with rate \eta_j(x), truncated to the interval
         * [0, \delta]
         */
        arma::fvec cnt_f = arma::conv_to<arma::fvec>::from(cnt);
        arma::fvec ones_vec(cnt_f.size(),arma::fill::ones);
        arma::fvec num_tables_k = arma::min(cnt_f, ones_vec);
        float num_customers = float(arma::sum(cnt));
        float num_tables = float(arma::sum(num_tables_k));
        
        /* 
         * Expected discount is averaging over time of cut which is
         * a truncated exponential
         */
        discount = (expo_param / (expo_param + settings_->discount_param)) *
            (-(exp(-(expo_param + settings_->discount_param) *
             max_split_costs_) - 1)) / 
            (-(exp(-expo_param * max_split_costs_)-1));

        float discount_per_num_customers = discount / num_customers;
        arma::fvec pred_prob_tmp = (num_tables * discount_per_num_customers *
            base) + (cnt_f / num_customers) - (discount_per_num_customers * 
            num_tables_k);

        pred_prob += prob_separated_now * prob_not_separated_yet * pred_prob_tmp;
        prob_not_separated_yet *= prob_not_separated_now;
    }
    /* c_j,k: number of customers at restaurant j eating dish k */     
    /* Compute posterior mean normalized stable */
    if (!is_leaf_) {
        if (equal(sample.x[split_dim_],split_loc_) || sample.x[split_dim_]
                < split_loc_) {

            if (settings_->debug) 
                cout << "left" << endl;
            pred_class = id_left_child_node_->predict_class(sample, pred_prob,
                    prob_not_separated_yet, m_conf);
        } else {
            if (settings_->debug) 
                cout << "right" << endl;
            pred_class = id_right_child_node_->predict_class(sample, pred_prob,
                    prob_not_separated_yet, m_conf);
        }
    } else if (is_leaf_ && greater_zero(expo_param) == false) {
        pred_prob = compute_posterior_mean_normalized_stable(
                cnt, discount, base) * prob_not_separated_yet;
    }
    /* Get class with highest probability */
    /* Check if all classes have same probability -> return -2 */
    if (equal_elements(pred_prob))
        return -2;
    float tmp_value = 0.;
    for (int i = 0; i < int(pred_prob.size()); i++) {
        if (pred_prob[i] > tmp_value) {
            tmp_value = pred_prob[i];
            pred_class = i;
        }
    }
    return pred_class;
}
void AlternateStoichiometries::createLevel2(std::vector<dense_vec> slowRxnFastStoich, std::vector<Reactants>& slowRxnFastReactantsReindexed) {
	dense_vec zero_vec(slowRxnFastStoich.size());
	for (std::size_t i=0; i!=zero_vec.size(); ++i) {
		zero_vec(i)=0;
	}
	
	for (std::size_t i=0; i!=fastReactions.size(); ++i) {
		for (std::size_t j=0; j!=fastReactions.size(); ++j) {
			AlternateStoichiometry tmpAltStoich;
			dense_vec stoich_i=fastReactions[i].getStoichiometry();//result of applying fast reaction i
			dense_vec stoich_j=fastReactions[j].getStoichiometry();//result of applying fast reaction j
			dense_vec stoich_iplusj=stoich_i+stoich_j;
//				std::cout << "stoich_"<<i<<"+stoich_"<<j<<":";
//				print_dense_vec(stoich_iplusj);
			tmpAltStoich.setStoich(stoich_iplusj);
			//create dependencies list
			Reactants reactants_i=fastReactions[i].getReactants();//slowRxnFastReactantsReindexed[i];
			Reactants reactants_j=fastReactions[j].getReactants();//slowRxnFastReactantsReindexed[j];

			tmpAltStoich.setDependency(AlternateStoichiometry::generateDependencyFromReactants(reactants_i));
			
			//dependency is all the reactants in reaction i (the first reaction) plus all the reactants from reaction j that were not created as products from reaction i
			//loop over reactants_j
			for (std::size_t k=0; k!=reactants_j.size(); ++k) {
				//see if reactants_j[k] was produced by rxn i
				int effectiveDependencyMoleculeCount=reactants_j[k].getMoleculeCount();
				if (stoich_i(reactants_j[k].getSpeciesIndex())>0) {
					effectiveDependencyMoleculeCount-=stoich_i(reactants_j[k].getSpeciesIndex());
				}
				//if effect count > 0, then add it to tmpreactants
				if (effectiveDependencyMoleculeCount>0) {
					tmpAltStoich.addDependency(reactants_j[k].getSpeciesIndex(),effectiveDependencyMoleculeCount);
				}
			}
			
			//now we have a (temp) alternate stoichiometry (including dependencies) that results when fast rxns i and j are fired
			//now we want to look at all the POSITIVE entries in the stoichiometry
			//because it's these positive entries that we can then use to fire a slow reaction that consumes those positive entries
			std::vector<std::size_t> listOfProducedSpecies;
			for (std::size_t k=0; k!=tmpAltStoich.getStoich().size(); ++k) {
				if (tmpAltStoich.getStoich()(k)>0) {
//						std::cout << "fast reactions "<<i<<" + "<<j<<" produces fast species index "<<k<<"\n";
					listOfProducedSpecies.push_back(k);
				}
			}
				
			//loop over the produced species and insert into oneReactantMoleculeLevels
//				std::cout << "list of produced species.size is "<<listOfProducedSpecies.size()<<"\n";
			for (std::size_t k=0; k!=listOfProducedSpecies.size(); ++k) {
				if (oneReactantMoleculeLevels.find(listOfProducedSpecies[k])==oneReactantMoleculeLevels.end()) {
//						std::cout << "inserting for species "<<listOfProducedSpecies[k]<<"\n";
					oneReactantMoleculeLevels.insert( std::pair<std::size_t,std::vector<AlternateStoichiometry > >(listOfProducedSpecies[k],std::vector<AlternateStoichiometry >()));//(1,tmpAltStoich)));
//						std::cout << "now oneReactantMoleculeLevels.size()="<<oneReactantMoleculeLevels.size()<<"\n";
				}

				//now an entry for the species exists in oneReactantMoleculeLevels
				//before inserting, see if an existing has a strictly weaker or equal dependency (if so, don't insert)
				bool existingEqualOrWeaker=false;
				std::vector<AlternateStoichiometry > currentAlts;
				currentAlts=(oneReactantMoleculeLevels.find(listOfProducedSpecies[k]))->second;
				for (std::size_t m=0; m!=currentAlts.size(); ++m) {
					if (currentAlts[m].dependencyIsEqualOrStrictlyWeaker(tmpAltStoich)) {
						existingEqualOrWeaker=true;
					}
				}
				if (existingEqualOrWeaker==false) {
					//we want to insert, but before we do, delete any where tmpAltStoich is strictly weaker than other
//						std::cout << "existingEqualOrWeaker is false...next erase entries where tmpAltStoich is strictly better...\n";
//						std::size_t sizebefore=currentAlts.size();
					currentAlts.erase(std::remove_if(currentAlts.begin(),currentAlts.end(),std::bind1st(std::mem_fun_ref(&AlternateStoichiometry::dependencyIsStrictlyWeakerNonRef),tmpAltStoich) ),currentAlts.end());
//						std::cout << "erased "<<sizebefore-currentAlts.size()<<" elements\n";
//						
//						std::cout << "now inserting tmpAltStoich...\n";
					//insert it into local copy, then copy local copy
					currentAlts.push_back(tmpAltStoich);
					oneReactantMoleculeLevels.find(listOfProducedSpecies[k])->second=currentAlts;
				}
			}
			//do a similar thing to insert into twoReactantMoleculeLevels
			//double loop over listOfProducedSpecies
//				std::cout << "look for two species opportunities (listOfProducedSpecies.size()="<<listOfProducedSpecies.size()<<"\n";
			for (std::size_t k=0; k!=listOfProducedSpecies.size(); ++k) {
				for (std::size_t m=k; m!=listOfProducedSpecies.size(); ++m) {	
					//if k==m, only makes sense if stoich(lops[k])>=2
					if (k==m && tmpAltStoich.getStoich()(listOfProducedSpecies[k])<2) {
//							std::cout << "don't bother with k=m ("<<k<<")\n";
						continue;
					}
				
					std::pair<std::size_t,std::size_t> reactantPair(listOfProducedSpecies[k],listOfProducedSpecies[m]);
//						std::cout << "pair "<<listOfProducedSpecies[k]<<","<<listOfProducedSpecies[m]<<"\n";
					if (twoReactantMoleculeLevels.find(reactantPair)==twoReactantMoleculeLevels.end()) {
//							std::cout << "inserting for species pair "<<listOfProducedSpecies[k]<<", "<<listOfProducedSpecies[m]<<"\n";
						twoReactantMoleculeLevels.insert( std::pair<  std::pair<std::size_t,std::size_t>,std::vector<AlternateStoichiometry > >(reactantPair,std::vector<AlternateStoichiometry >()));//(1,tmpAltStoich)));
//							std::cout << "now twoReactantMoleculeLevels.size()="<<twoReactantMoleculeLevels.size()<<"\n";
					}

					//now entry exists in twoReactantMoleculeLevels
					//insert altStoich into vector and/or delete inferior existing elements as necessary
					//before inserting, see if an existing has a strictly weaker or equal dependency (if so, don't insert)
					bool existingEqualOrWeaker2=false;
					std::vector<AlternateStoichiometry > currentAlts=(twoReactantMoleculeLevels.find(reactantPair))->second;
					for (std::size_t m=0; m!=currentAlts.size(); ++m) {
						if (currentAlts[m].dependencyIsEqualOrStrictlyWeaker(tmpAltStoich)) {
							existingEqualOrWeaker2=true;
						}
					}
					if (existingEqualOrWeaker2==false) {
						//we want to insert, but before we do, delete any where tmpAltStoich is strictly weaker than other
//							std::cout << "existingEqualOrWeaker is false...next erase entries where tmpAltStoich is strictly better...\n";
//							std::size_t sizebefore=currentAlts.size();
						currentAlts.erase(std::remove_if(currentAlts.begin(),currentAlts.end(),std::bind1st(std::mem_fun_ref(&AlternateStoichiometry::dependencyIsStrictlyWeakerNonRef),tmpAltStoich) ),currentAlts.end());
//							std::cout << "erased "<<sizebefore-currentAlts.size()<<" elements\n";
						
//							std::cout << "now inserting tmpAltStoich...\n";
						//insert it into local copy, then copy local copy
						currentAlts.push_back(tmpAltStoich);
						twoReactantMoleculeLevels.find(reactantPair)->second=currentAlts;
					}


				}
			}
			
		}
	}
	
//		std::cout << "AFTER LEVEL 2...\n";
//		std::cout << "SINGLE MOLECULE:\n";
//	typedef std::map<std::size_t,std::vector<AlternateStoichiometry > > mapone;
//	mapone::iterator it;
//		for (it=oneReactantMoleculeLevels.begin(); it!=oneReactantMoleculeLevels.end(); ++it) {
//			std::cout << "for species "<<it->first<<":\n";
//			for (std::size_t i=0; i!=it->second.size(); ++i) {
//				it->second[i].display();
//			}
//		}
//		std::cout << "TWO MOLECULE:\n";
//	typedef std::map< std::pair<std::size_t,std::size_t> ,std::vector<AlternateStoichiometry > > maptwo;
//	maptwo::iterator it2;
//		for (it2=twoReactantMoleculeLevels.begin(); it2!=twoReactantMoleculeLevels.end(); ++it2) {
//			std::cout << "for species "<<it2->first.first<<", "<<it2->first.second<<":\n";
//			for (std::size_t i=0; i!=it2->second.size(); ++i) {
//				it2->second[i].display();
//			}
//		}		
}
Esempio n. 11
0
void FGRotor::rotor::zero() {
  FGColumnVector3 zero_vec(0.0, 0.0, 0.0);

  flags               = 0;
  parent              = NULL  ;

  reports             = 0;

  // configuration
  Radius              = 0.0 ;
  BladeNum            = 0   ;
  RelDistance_xhub    = 0.0 ;
  RelShift_yhub       = 0.0 ;
  RelHeight_zhub      = 0.0 ;
  NominalRPM          = 0.0 ;
  MinRPM              = 0.0 ;
  BladeChord          = 0.0 ;
  LiftCurveSlope      = 0.0 ;
  BladeFlappingMoment = 0.0 ;
  BladeTwist          = 0.0 ;
  BladeMassMoment     = 0.0 ;
  TipLossB            = 0.0 ;
  PolarMoment         = 0.0 ;
  InflowLag           = 0.0 ;
  ShaftTilt           = 0.0 ;
  HingeOffset         = 0.0 ;
  HingeOffset_hover   = 0.0 ;
  CantAngleD3         = 0.0 ;

  theta_shaft         = 0.0 ;
  phi_shaft           = 0.0 ;

  // derived parameters
  LockNumberByRho     = 0.0 ;
  solidity            = 0.0 ;
  RpmRatio            = 0.0 ;

  for (int i=0; i<5; i++) R[i] = 0.0;
  for (int i=0; i<6; i++) B[i] = 0.0;

  BodyToShaft.InitMatrix();
  ShaftToBody.InitMatrix();

  // dynamic values
  ActualRPM           = 0.0 ;
  Omega               = 0.0 ;
  beta_orient         = 0.0 ;
  a0                  = 0.0 ;
  a_1 = b_1 = a_dw    = 0.0 ;
  a1s = b1s           = 0.0 ;
  H_drag = J_side     = 0.0 ;

  Torque              = 0.0 ;
  Thrust              = 0.0 ;
  Ct                  = 0.0 ;
  lambda              = 0.0 ;
  mu                  = 0.0 ;
  nu                  = 0.0 ;
  v_induced           = 0.0 ;

  force      = zero_vec ;
  moment     = zero_vec ;

}