void TagVertexMesh::copy_all_coordinates( MsqError& err )
{
  if (!haveTagHandle) {
    tagHandle = get_mesh()->tag_create( tagName, Mesh::DOUBLE, 3, 0, err ); 
    MSQ_ERRRTN(err);
    haveTagHandle = true;
  }

  std::vector<Mesh::VertexHandle> handles;
  get_all_vertices( handles, err ); 
  MSQ_ERRRTN(err);
  if (handles.empty())
    return;
  
  std::vector<MsqVertex> coords(handles.size());
  get_mesh()->vertices_get_coordinates( arrptr(handles), arrptr(coords), handles.size(), err );
  MSQ_ERRRTN(err);
  
  std::vector<double> data( 3*handles.size() );
  std::vector<double>::iterator j = data.begin();
  std::vector<MsqVertex>::const_iterator i = coords.begin();
  while (i != coords.end()) {
    i->get_coordinates( &*j );
    ++i;
    j += 3;
  }
  
  tag_set_vertex_data( tagHandle, handles.size(), arrptr(handles), arrptr(data), err );
  MSQ_ERRRTN(err);
}
Exemple #2
0
void make_local_mesh(Mesh *me)
{
	Object *ob;
	Mesh *men;
	int local=0, lib=0;

	/* - only lib users: do nothing
	    * - only local users: set flag
	    * - mixed: make copy
	    */
	
	if(me->id.lib==0) return;
	if(me->id.us==1) {
		me->id.lib= 0;
		me->id.flag= LIB_LOCAL;
		new_id(0, (ID *)me, 0);
		
		if(me->mtface) make_local_tface(me);
		
		return;
	}
	
	ob= G.main->object.first;
	while(ob) {
		if( me==get_mesh(ob) ) {
			if(ob->id.lib) lib= 1;
			else local= 1;
		}
		ob= ob->id.next;
	}
	
	if(local && lib==0) {
		me->id.lib= 0;
		me->id.flag= LIB_LOCAL;
		new_id(0, (ID *)me, 0);
		
		if(me->mtface) make_local_tface(me);
		
	}
	else if(local && lib) {
		men= copy_mesh(me);
		men->id.us= 0;
		
		ob= G.main->object.first;
		while(ob) {
			if( me==get_mesh(ob) ) {				
				if(ob->id.lib==0) {
					set_mesh(ob, men);
				}
			}
			ob= ob->id.next;
		}
	}
}
Exemple #3
0
void MeshData::triangulate(int idx) {
  auto copy0 = std::unique_ptr<Surface_mesh> {new Surface_mesh(get_mesh(0))};
  auto copy1 = std::unique_ptr<Surface_mesh> {new Surface_mesh(get_mesh(1))};

  qDebug() << "Triangulating mesh" << idx;

  if (idx == 0) {
    copy0->triangulate();
  } else {
    copy1->triangulate();
  }
  history_push({std::move(copy0), std::move(copy1)});

  emit_updated_signal();
}
Real DerivedRBConstruction<RBConstruction>::truth_solve(int plot_solution)
{
  START_LOG("truth_solve()", "DerivedRBConstruction");

  EquationSystems& es = this->get_equation_systems();
  RBConstruction& uber_system = es.get_system<RBConstruction>(uber_system_name);

  set_uber_current_parameters();

  uber_system.get_rb_evaluation().set_parameters(uber_system.get_parameters());
  uber_system.get_rb_evaluation().rb_solve(uber_system.get_rb_evaluation().get_n_basis_functions());

  if(plot_solution > 0)
  {
    uber_system.load_rb_solution();
    *solution = *(uber_system.solution);

#ifdef LIBMESH_HAVE_EXODUS_API
    ExodusII_IO(get_mesh()).write_equation_systems ("unter_uber_truth.e",
                                              this->get_equation_systems());
#endif
  }

  STOP_LOG("truth_solve()", "DerivedRBConstruction");

  // Don't bother returning the norm of the uber solution
  return 0.;
}
Exemple #5
0
/*  (similar to void paintface_flush_flags(Object *ob))
 * copy the vertex flags, most importantly selection from the mesh to the final derived mesh,
 * use in object mode when selecting vertices (while painting) */
void paintvert_flush_flags(Object *ob)
{
	Mesh *me= get_mesh(ob);
	DerivedMesh *dm= ob->derivedFinal;
	MVert *dm_mvert, *dm_mv;
	int *index_array = NULL;
	int totvert;
	int i;

	if(me==NULL || dm==NULL)
		return;

	index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);

	dm_mvert = dm->getVertArray(dm);
	totvert = dm->getNumVerts(dm);

	dm_mv= dm_mvert;

	if(index_array) {
		int orig_index;
		for (i= 0; i<totvert; i++, dm_mv++) {
			orig_index= index_array[i];
			if(orig_index != ORIGINDEX_NONE) {
				dm_mv->flag= me->mvert[index_array[i]].flag;
			}
		}
	}
	else {
		for (i= 0; i<totvert; i++, dm_mv++) {
			dm_mv->flag= me->mvert[i].flag;
		}
	}
}
Exemple #6
0
void compute_point_emission()
{
	t_mesh *mesh = get_mesh();
	unsigned int i,j,point_id;
	int i_t_le,i_t_kappa,i_t_fQ,i_h2o;
	double kappa,emission=0;
	mesh->max_emission = 0;

	for(i=0;i<mesh->nb_points;i++)
	{
		mesh->points[i].emission = 0;
	}
	for(i=0;i<mesh->nb_point_to_compute;i++)
	{
		point_id = mesh->point_to_compute[i];
		compute_index(mesh->points[point_id].temperature, mesh->points[point_id].h2o, &i_t_le, &i_t_kappa, &i_t_fQ, &i_h2o);
		for(j=0;j<NB_BAND;j++)
		{
			kappa = mesh->point_presure * mesh->points[i].h2o * mesh->ckmodel.fQH_store[i_t_fQ] * mesh->ckmodel.kappa_h2o_store[j][i_t_kappa][i_h2o] + 
				mesh->point_presure * mesh->points[i].co2 * mesh->ckmodel.fQC_store[i_t_fQ] * mesh->ckmodel.kappa_co2_store[j][i_t_kappa];
			emission = emission + kappa*mesh->ckmodel.le_store[j][i_t_le];
		}
		mesh->points[i].emission = FOUR_PI * emission;
		if(mesh->points[i].emission > mesh->max_emission)
			mesh->max_emission = mesh->points[i].emission;
	}
}
void TagVertexMesh::vertex_set_coordinates( VertexHandle vertex,
                                            const Vector3D &coordinates,
                                            MsqError &err )
{
  if (!haveTagHandle)
  {
    tagHandle = get_mesh()->tag_create( tagName, Mesh::DOUBLE, 3, 0, err ); 
    MSQ_ERRRTN(err);
    haveTagHandle = true;
    copy_all_coordinates( err );
    MSQ_ERRRTN(err);  
  }
  
  get_mesh()->tag_set_vertex_data( tagHandle, 1, &vertex, coordinates.to_array(), err );
  MSQ_ERRRTN(err);
}
Exemple #8
0
	void MeshCache::get_mesh(const String &name,
		AbstractMeshSharedPtr &mesh)
	{
		StringVector materials;

		get_mesh(name, mesh, materials);
	}
Exemple #9
0
void SoftBody::update_physics_server() {

	if (Engine::get_singleton()->is_editor_hint())
		return;

	if (get_mesh().is_valid()) {

		become_mesh_owner();
		PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh());
		VS::get_singleton()->connect("frame_pre_draw", this, "_draw_soft_mesh");
	} else {

		PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, NULL);
		VS::get_singleton()->disconnect("frame_pre_draw", this, "_draw_soft_mesh");
	}
}
void TagVertexMesh::initialize( Mesh* mesh, std::string name, MsqError& err )
{
  MeshDecorator::set_mesh( mesh );
  tagName = name;

  tagHandle = get_mesh()->tag_get( tagName, err );
    // If tag isn't defined yet, we're done for now.
  if (err.error_code() == MsqError::TAG_NOT_FOUND) {
    err.clear();
    return;
  } 
  else if (MSQ_CHKERR(err))
    return;
  
    // If tag is already defined, make sure it is the correct type.
  std::string t_name;
  Mesh::TagType type;
  unsigned length;
  tag_properties( tagHandle, t_name, type, length, err ); 
  MSQ_ERRRTN(err);
  if (!(type == Mesh::DOUBLE && length == 3) &&
      !(type == Mesh::BYTE && length == 3*sizeof(double)))
    MSQ_SETERR(err)(MsqError::TAG_ALREADY_EXISTS,
                    "Tag \"%s\" has invalid type or size.",
                    tagName.c_str());
 
    // If tag is already defined and init was true, reset tag
    // values.
  haveTagHandle = true;
}
Exemple #11
0
void interpolation_coef_CK(double T, double xh2o, int *iTCK, int *ixCK, double *ciT1, double *ciT2, double *cix1, double *cix2)
{
	t_ck_model *ckmodel = &get_mesh()->ckmodel;
	int j;
	if(T <= ckmodel->temp_pmg[0])
	{
		*iTCK = 1;
		*ciT1 = 1;
		*ciT2 = 0;
	}
	else if(T >= ckmodel->temp_pmg[nb_temp_CK-1])
	{
		*iTCK = nb_temp_CK - 1;
		*ciT2 = 0;
		*ciT2 = 1;
	}
	else
	{
		for(j = 1; T > ckmodel->temp_pmg[j]; j++)
		{

		}
		*iTCK = j;
		*ciT2 = (T-ckmodel->temp_pmg[j] / (ckmodel->temp_pmg[j]-ckmodel->temp_pmg[j-1]) );
		*ciT1 = 1 - *ciT2;
	}
	for(j=0;xh2o > ckmodel->xh2o_CK[j];j++)
	{

	}
	*ixCK = j;
	*cix2 = (xh2o-ckmodel->xh2o_CK[j]/(ckmodel->xh2o_CK[j]-ckmodel->xh2o_CK[j]));
	*cix1 = 1 - *cix2;
}
Exemple #12
0
	void Object::update_bounding_box()
	{
		BoundingBox bounding_box;

		get_mesh()->get_bounding_box(get_world_transformation(),
			bounding_box);
		set_bounding_box(bounding_box);
	}
Exemple #13
0
/*  note: if the caller passes FALSE to flush_flags, then they will need to run paintvert_flush_flags(ob) themselves */
void paintvert_deselect_all_visible(Object *ob, int action, short flush_flags)
{
	Mesh *me;
	MVert *mvert;
	int a;

	me= get_mesh(ob);
	if(me==NULL) return;
	
	if(action == SEL_INVERT) {
		mvert= me->mvert;
		a= me->totvert;
		while(a--) {
			if((mvert->flag & ME_HIDE) == 0) {
				mvert->flag ^= SELECT;
			}
			mvert++;
		}
	}
	else {
		if (action == SEL_TOGGLE) {
			action = SEL_SELECT;

			mvert= me->mvert;
			a= me->totvert;
			while(a--) {
				if((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) {
					action = SEL_DESELECT;
					break;
				}
				mvert++;
			}
		}

		mvert= me->mvert;
		a= me->totvert;
		while(a--) {
			if((mvert->flag & ME_HIDE) == 0) {
				switch (action) {
				case SEL_SELECT:
					mvert->flag |= SELECT;
					break;
				case SEL_DESELECT:
					mvert->flag &= ~SELECT;
					break;
				case SEL_INVERT:
					mvert->flag ^= SELECT;
					break;
				}
			}
			mvert++;
		}
	}

	if(flush_flags) {
		paintvert_flush_flags(ob);
	}
}
Exemple #14
0
cCellMesh::cCellMesh(std::string file_name){
	// initialise member variables
	nodes_count = 0;
	total_elements_count = 0;
	surface_elements_count = volume_elements_count = 0;

	get_mesh(file_name); /* rank 0 only??? */
	calc_dist();
}
Exemple #15
0
bool MeshData::persist(const std::string& filename, int idx) const {
  if (filename.empty()) {
    qWarning() << "File name empty. Aborting persisting.";
    return false;
  }
  qDebug() << "Persisted mesh.";

  return get_mesh(idx).write(filename);
}
Exemple #16
0
void GlobalPatch::get_patch( PatchHandle patch_handle,
                             std::vector<Mesh::ElementHandle>& elem_handles_out,
                             std::vector<Mesh::VertexHandle>& free_vertices_out,
                             MsqError& err )
{
  free_vertices_out.clear();
  assert(GLOBAL_PATCH_HANDLE == patch_handle);
  get_mesh()->get_all_elements( elem_handles_out, err ); MSQ_ERRRTN(err);
  //get_mesh()->get_all_vertices( free_vertices_out, err ); MSQ_ERRRTN(err);
}
Exemple #17
0
void compute_point_emission_surface()
{
	t_mesh *mesh = get_mesh();
	unsigned int i,point_id;
	printf("nb_bouudary_point_to_compute:%d\n",mesh->nb_boundary_point_to_compute);
	for(i=0;i<mesh->nb_boundary_point_to_compute;i++)
	{
		point_id = mesh->boundary_point_to_compute[i];
		mesh->points[point_id].emission_surface = mesh->epsilon_paro * constant_stefan * pow(mesh->points[point_id].temperature,4);
	}
}
Exemple #18
0
void SoftBody::_draw_soft_mesh() {
	if (get_mesh().is_null())
		return;

	if (!visual_server_handler.is_ready()) {

		visual_server_handler.prepare(get_mesh()->get_rid(), 0);

		/// Necessary in order to render the mesh correctly (Soft body nodes are in global space)
		simulation_started = true;
		call_deferred("set_as_toplevel", true);
		call_deferred("set_transform", Transform());
	}

	visual_server_handler.open();
	PhysicsServer::get_singleton()->soft_body_update_visual_server(physics_rid, &visual_server_handler);
	visual_server_handler.close();

	visual_server_handler.commit_changes();
}
TagHandle TagVertexMesh::tag_get( const std::string& name, MsqError& err )
{
    // Don't allow access to internal tag for vertex coordinates.
    // This prevents accidental layering of multiple instances of
    // TagVertexMesh with the same tag name.
  if (name == tagName) {
    MSQ_SETERR(err)("Attempt to access internal tag data using tag interface.",
                    MsqError::INVALID_ARG);
    return (TagHandle)0;
  }
  
  return get_mesh()->tag_get( name, err );
}
Exemple #20
0
void compute_kappa_le_simple(int nu, double temperature, double co2, double h2o, double *kappa, double *le)
{
	t_mesh *mesh = get_mesh();
	int i_t_le, i_t_kappa, i_t_fQ, i_h2o;
	double t, x_h2o, x_co2;
	t = temperature;
	x_h2o = h2o;
	x_co2 = co2;
	compute_index(t, x_h2o, &i_t_le, &i_t_kappa, &i_t_fQ, &i_h2o);
	*kappa = mesh->point_presure * x_h2o * mesh->ckmodel.fQH_store[i_t_fQ] * mesh->ckmodel.kappa_h2o_store[nu][i_t_kappa][i_h2o] + 
		mesh->point_presure * x_co2 *mesh->ckmodel.fQC_store[i_t_fQ] * mesh->ckmodel.kappa_co2_store[nu][i_t_kappa];
	*le = mesh->ckmodel.le_store[nu][i_t_le];
}
Exemple #21
0
ArcballHelper ArcballHelper::create(gst::ProgramPool & programs)
{
    auto camera = std::unique_ptr<gst::Camera>(new gst::OrthoCamera());
    auto eye = std::make_shared<gst::CameraNode>(std::move(camera));

    auto create_model_node = [&programs]()
    {
        auto basic_program = programs.create(BASIC_VS, BASIC_FS);
        auto basic_pass = std::make_shared<gst::BasicPass>(basic_program);

        auto vertex_array = std::make_shared<gst::VertexArrayImpl>();
        auto mesh = gst::Mesh(vertex_array);
        auto material = gst::Material::create_free();
        auto model = gst::Model(mesh, material, basic_pass);

        return std::make_shared<gst::ModelNode>(model);
    };

    auto result_node = create_model_node();
    result_node->get_mesh().set_draw_mode(gst::DrawMode::LINE_STRIP);

    auto rim_node = create_model_node();
    rim_node->get_mesh().set_draw_mode(gst::DrawMode::LINE_LOOP);
    rim_node->get_material().get_uniform("opacity") = 0.4f;
    rim_node->get_pass().set_blend_mode(gst::BlendMode::INTERPOLATIVE);

    auto drag_node = create_model_node();
    drag_node->get_mesh().set_draw_mode(gst::DrawMode::LINE_STRIP);

    ConstraintNodes constraint_nodes;
    for (int i = 0; i < 3; i++) {
        constraint_nodes[i] = create_model_node();
        constraint_nodes[i]->get_mesh().set_draw_mode(gst::DrawMode::LINE_STRIP);
        constraint_nodes[i]->get_pass().set_blend_mode(gst::BlendMode::INTERPOLATIVE);
    }

    return ArcballHelper(eye, drag_node, rim_node, result_node, constraint_nodes);
}
double TagVertexMesh::loop_over_mesh( MeshDomainAssoc* mesh_and_domain,
                                      const Settings* ,
                                      MsqError& err )
{
  Mesh* mesh = mesh_and_domain->get_mesh();
  if (mesh != get_mesh()) {
    MSQ_SETERR(err)("InstructionQueue and TagVertexMesh have different "
                    "Mesquite::Mesh instances.  Cannot initialize TagVertexMesh",
                    MsqError::INVALID_MESH);
    return 0.0;
  }
  
  copy_all_coordinates( err ); MSQ_ERRZERO(err);
  return 0.0;
}
void TagVertexMesh::vertices_get_coordinates( const VertexHandle vert_array[],
                                              MsqVertex* coordinates,
                                              size_t num_vtx,
                                              MsqError &err )
{
  if (!num_vtx)
    return;
  if (!haveTagHandle) {
    get_mesh()->vertices_get_coordinates( vert_array, coordinates, num_vtx, err );
    MSQ_ERRRTN(err);
  }
  else {
    std::vector<double> coords( num_vtx * 3 );
    get_mesh()->tag_get_vertex_data( tagHandle, num_vtx, vert_array, arrptr(coords), err );
    MSQ_ERRRTN(err);
    MsqVertex* coordinates_end = coordinates + num_vtx;
    std::vector<double>::const_iterator i = coords.begin();
    while (coordinates != coordinates_end) {
      coordinates->set( &*i );
      i += 3;
      ++coordinates;
    }
  }
}
TagHandle TagVertexMesh::tag_create( const std::string& tag_name,
                                     TagType type, unsigned length,
                                     const void* default_value,
                                     MsqError &err)
{
    // Don't allow access to internal tag for vertex coordinates.
    // This prevents accidental layering of multiple instances of
    // TagVertexMesh with the same tag name.
  if (tag_name == tagName) {
    MSQ_SETERR(err)("Attempt to access internal tag data using tag interface.",
                    MsqError::TAG_ALREADY_EXISTS);
    return (TagHandle)0;
  }
  
  return get_mesh()->tag_create( tag_name, type, length, default_value, err );
}
Exemple #25
0
	void TerrainPage::update_bounding_box()
	{
		BoundingBox bounding_box;
		glm::vec3 min, max;

		get_mesh()->get_bounding_box(Transformation(), bounding_box);

		min = bounding_box.get_min();
		max = bounding_box.get_max();

		min.z = get_min_z();
		max.z = get_max_z();

		bounding_box.set_min_max(min, max);

		set_bounding_box(bounding_box.transform(
			get_world_transformation()));
	}
Exemple #26
0
/* Returns 0 on success, 1 if the src's totvert doesn't match */
int multiresModifier_reshape(MultiresModifierData *mmd, Object *dst, Object *src)
{
    Mesh *src_me = get_mesh(src);
    DerivedMesh *mrdm = dst->derivedFinal;

    if(mrdm && mrdm->getNumVerts(mrdm) == src_me->totvert) {
        MVert *mvert = CDDM_get_verts(mrdm);
        int i;

        for(i = 0; i < src_me->totvert; ++i)
            VecCopyf(mvert[i].co, src_me->mvert[i].co);
        mrdm->needsFree = 1;
        MultiresDM_mark_as_modified(mrdm);
        mrdm->release(mrdm);
        dst->derivedFinal = NULL;

        return 0;
    }

    return 1;
}
Exemple #27
0
String SoftBody::get_configuration_warning() const {

	String warning = MeshInstance::get_configuration_warning();

	if (get_mesh().is_null()) {
		if (!warning.empty())
			warning += "\n\n";

		warning += TTR("This body will be ignored until you set a mesh");
	}

	Transform t = get_transform();
	if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(0).length() - 1.0) > 0.05)) {
		if (!warning.empty())
			warning += "\n\n";

		warning += TTR("Size changes to SoftBody will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.");
	}

	return warning;
}
Exemple #28
0
int get_nu_face(int point)
{
	t_mesh *mesh = get_mesh();
	int i_t_le, i_t_kappa, i_t_fQ, i_h2o, nu;
	unsigned int i_nu;
	double cumulative_energy, cumulative_energy_old, rand_number;
	rand_number = nrand() * mesh->points[point].emission_surface / FOUR_PI / mesh->point_presure;
	cumulative_energy = 0;
	nu = 0;
	for(i_nu=0;i_nu<NB_BAND;i_nu++)
	{
		compute_index(mesh->points[point].temperature, mesh->points[point].h2o, &i_t_le, &i_t_kappa, &i_t_fQ, &i_h2o);
		cumulative_energy_old = cumulative_energy;
		cumulative_energy = cumulative_energy + mesh->epsilon_paro * mesh->ckmodel.le_store[i_nu][i_t_le];
		if(rand_number <= cumulative_energy && rand_number > cumulative_energy_old)
		{
			nu = i_nu;
			break;
		}
	}
	return nu;
}
Exemple #29
0
int get_nu(int point)
{
	t_mesh *mesh = get_mesh();
	int i_t_le, i_t_kappa, i_t_fQ, i_h2o, nu;
	unsigned int i_nu;
	double cumulative_energy, cumulative_energy_old, kappa, rand_number;
	rand_number = nrand() * mesh->points[point].emission / FOUR_PI /mesh->point_presure;
	cumulative_energy = 0;
	nu = 0;
	for(i_nu=0;i_nu<NB_BAND;i_nu++)
	{
		compute_index(mesh->points[point].temperature, mesh->points[point].h2o, &i_t_le, &i_t_kappa, &i_t_fQ, &i_h2o);
		cumulative_energy_old = cumulative_energy;
		kappa = mesh->points[point].h2o * mesh->ckmodel.fQH_store[i_t_fQ] * mesh->ckmodel.kappa_h2o_store[i_nu][i_t_kappa][i_h2o] +  
			mesh->points[point].co2 * mesh->ckmodel.fQC_store[i_t_fQ] * mesh->ckmodel.kappa_co2_store[i_nu][i_t_kappa];
		cumulative_energy = cumulative_energy + kappa * mesh->ckmodel.le_store[i_nu][i_t_le];
		if(rand_number <= cumulative_energy && rand_number > cumulative_energy_old)
		{
			nu = i_nu;
			break;
		}
	}
	return nu;
}
Exemple #30
0
Real RBEIMConstruction::truth_solve(int plot_solution)
{
  START_LOG("truth_solve()", "RBEIMConstruction");

//  matrix should have been set to inner_product_matrix during initialization
//  if(!single_matrix_mode)
//  {
//    matrix->zero();
//    matrix->add(1., *inner_product_matrix);
//  }
//  else
//  {
//    assemble_inner_product_matrix(matrix);
//  }

  int training_parameters_found_index = -1;
  if( _parametrized_functions_in_training_set_initialized )
  {
    // Check if parameters are in the training set. If so, we can just load the
    // solution from _parametrized_functions_in_training_set

    for(unsigned int i=0; i<get_n_training_samples(); i++)
    {
      if(get_parameters() == get_params_from_training_set(i))
      {
        training_parameters_found_index = i;
        break;
      }
    }
  }

  // If the parameters are in the training set, just copy the solution vector
  if(training_parameters_found_index >= 0)
  {
    *solution = *_parametrized_functions_in_training_set[training_parameters_found_index];
    update(); // put the solution into current_local_solution as well
  }
  // Otherwise, we have to compute the projection
  else
  {
    RBEIMEvaluation& eim_eval = libmesh_cast_ref<RBEIMEvaluation&>(get_rb_evaluation());
    eim_eval.set_parameters( get_parameters() );

    // Compute truth representation via projection
    const MeshBase& mesh = this->get_mesh();

    AutoPtr<FEMContext> c = this->build_context();
    FEMContext &context  = libmesh_cast_ref<FEMContext&>(*c);

    this->init_context(context);

    rhs->zero();

    MeshBase::const_element_iterator       el     = mesh.active_local_elements_begin();
    const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end();

    for ( ; el != end_el; ++el)
    {
      context.pre_fe_reinit(*this, *el);
      context.elem_fe_reinit();

      for(unsigned int var=0; var<n_vars(); var++)
      {
        const std::vector<Real> &JxW =
          context.element_fe_var[var]->get_JxW();

        const std::vector<std::vector<Real> >& phi =
          context.element_fe_var[var]->get_phi();

        const std::vector<Point> &xyz =
          context.element_fe_var[var]->get_xyz();

        unsigned int n_qpoints = context.element_qrule->n_points();
        unsigned int n_var_dofs = libmesh_cast_int<unsigned int>
	  (context.dof_indices_var[var].size());

        DenseSubVector<Number>& subresidual_var = *context.elem_subresiduals[var];

        for(unsigned int qp=0; qp<n_qpoints; qp++)
          for(unsigned int i=0; i != n_var_dofs; i++)
            subresidual_var(i) += JxW[qp] * eim_eval.evaluate_parametrized_function(var, xyz[qp]) * phi[i][qp];
      }

      // Apply constraints, e.g. periodic constraints
      this->get_dof_map().constrain_element_vector(context.get_elem_residual(), context.dof_indices);

      // Add element vector to global vector
      rhs->add_vector(context.get_elem_residual(), context.dof_indices);
    }

    // Solve to find the best fit, then solution stores the truth representation
    // of the function to be approximated
    solve();

    // Make sure we didn't max out the number of iterations
    if( (this->n_linear_iterations() >=
         this->get_equation_systems().parameters.get<unsigned int>("linear solver maximum iterations")) &&
        (this->final_linear_residual() >
         this->get_equation_systems().parameters.get<Real>("linear solver tolerance")) )
    {
        libMesh::out << "Warning: Linear solver may not have converged! Final linear residual = "
                     << this->final_linear_residual() << ", number of iterations = "
                     << this->n_linear_iterations() << std::endl << std::endl;
  //     libmesh_error();
    }

    if(reuse_preconditioner)
    {
      // After we've done a solve we can now reuse the preconditioner
      // because the matrix is not changing
      linear_solver->reuse_preconditioner(true);
    }
  }

  if(plot_solution > 0)
  {
#ifdef LIBMESH_HAVE_EXODUS_API
    ExodusII_IO(get_mesh()).write_equation_systems ("truth.e",
                                                    this->get_equation_systems());
#endif
  }

  STOP_LOG("truth_solve()", "RBEIMConstruction");

  return 0.;
}