void
GMessageViewDir::BuildWindow
	(
	const JString& mailfile
	)
{
	JSize w = 500;
	JSize h = 300;
	JXWindow* window = new JXWindow(this, w,h, mailfile);
    assert( window != NULL );

	window->SetWMClass(GMGetWMClassInstance(), GMGetViewWindowClass());
    GGetPrefsMgr()->GetViewWindowSize(window);
	w = window->GetFrameWidth();
	h = window->GetFrameHeight();

    window->SetMinSize(w, 150);
    window->ShouldFocusWhenShow(kJTrue);

	JXMenuBar* menuBar =
		new JXMenuBar(window,
			JXWidget::kHElastic, JXWidget::kFixedTop,
			0, 0, w - kJXDefaultMenuBarHeight, kJXDefaultMenuBarHeight);
	assert(menuBar != NULL);

	JXEngravedRect* eRect =
		new JXEngravedRect(window,
			JXWidget::kFixedRight, JXWidget::kFixedTop,
			w - kJXDefaultMenuBarHeight, 0, kJXDefaultMenuBarHeight, kJXDefaultMenuBarHeight);
	assert(eRect != NULL);

	GMMessageDragSource* mds =
		new GMMessageDragSource(this, window,
			JXWidget::kFixedRight, JXWidget::kFixedTop,
			w - kJXDefaultMenuBarHeight + kJXDefaultBorderWidth,
			0 + kJXDefaultBorderWidth,
			kJXDefaultMenuBarHeight - 2 * kJXDefaultBorderWidth + 1,
			kJXDefaultMenuBarHeight - 2 * kJXDefaultBorderWidth + 1);
	assert(mds != NULL);

	itsFileMenu = menuBar->AppendTextMenu(kFileMenuTitleStr);
	itsFileMenu->SetMenuItems(kFileMenuStr);
	itsFileMenu->SetUpdateAction(JXMenu::kDisableNone);
	ListenTo(itsFileMenu);

	JPtrArray<JString> nodes(JPtrArrayT::kDeleteAll);
	GGetMailboxTreeDir()->GetTopLevelNodes(&nodes);

	itsTransferMenu = new JXFSDirMenu(nodes, itsFileMenu, kTransferToCmd, menuBar);
	assert(itsTransferMenu != NULL);
	ListenTo(itsTransferMenu);

	JDirInfo* info;
	if (itsTransferMenu->GetDirInfo(&info))
		{
		info->SetContentFilter(GMGetMailRegexStr());
		}

	itsCopyMenu = new JXFSDirMenu(nodes, itsFileMenu, kCopyToCmd, menuBar);
	assert(itsCopyMenu != NULL);
	ListenTo(itsCopyMenu);

	if (itsCopyMenu->GetDirInfo(&info))
		{
		info->SetContentFilter(GMGetMailRegexStr());
		}

	ListenTo(GGetMailboxTreeDir());

	itsMessageMenu = menuBar->AppendTextMenu(kMessageMenuTitleStr);
	itsMessageMenu->SetMenuItems(kMessageMenuStr);
	itsMessageMenu->SetUpdateAction(JXMenu::kDisableNone);
	ListenTo(itsMessageMenu);

	itsToolBar =
		new JXToolBar(GGetPrefsMgr(), kGViewToolBarID,
			menuBar, w, 150, window,
			JXWidget::kHElastic, JXWidget::kVElastic,
			0, kJXDefaultMenuBarHeight, w, h - kJXDefaultMenuBarHeight);
	assert(itsToolBar != NULL);

	const JSize newHeight	= itsToolBar->GetWidgetEnclosure()->GetBoundsHeight();

	const JFontManager* fm	= window->GetFontManager();
	JSize lineHeight =
		fm->GetLineHeight(GGetPrefsMgr()->GetDefaultMonoFont(),
						  GGetPrefsMgr()->GetDefaultFontSize(),
						  JFontStyle());


	const JCoordinate headerheight  = (lineHeight * 4) + (lineHeight/2); //58;

	JArray<JCoordinate> sizes;
	JArray<JCoordinate> minSizes;

	sizes.AppendElement(headerheight);
	minSizes.AppendElement(20);
	sizes.AppendElement(w - headerheight);
	minSizes.AppendElement(50);
	JIndex elasticIndex = 2;

	itsPart =
		new JXVertPartition(sizes, elasticIndex,
			minSizes, itsToolBar->GetWidgetEnclosure(),
			JXWidget::kHElastic, JXWidget::kVElastic,
			0, 0,
			w, newHeight);
	assert(itsPart != NULL);

	itsSBSet =
		new JXScrollbarSet(itsPart->GetCompartment(2),
			JXWidget::kHElastic, JXWidget::kVElastic,
			0,0,
			100,100);
	assert(itsSBSet != NULL);
	itsSBSet->FitToEnclosure(kJTrue, kJTrue);

	itsView =
		new GMessageView(menuBar, itsSBSet, itsSBSet->GetScrollEnclosure(),
			JXWidget::kHElastic, JXWidget::kVElastic,
			0,0,10,10);
	assert (itsView != NULL);
	itsView->FitToEnclosure(kJTrue, kJTrue);
	itsView->SetPTPrinter(GMGetAltPTPrinter());

	window->InstallShortcuts(itsView, "#_");
	ListenTo(itsView);

	JXScrollbarSet* sbs =
		new JXScrollbarSet(itsPart->GetCompartment(1),
			JXWidget::kHElastic, JXWidget::kVElastic,
			0,0,
			100,50);
	assert(sbs != NULL);
	sbs->FitToEnclosure(kJTrue, kJTrue);

	itsHeader =
		new GMessageView(sbs, sbs->GetScrollEnclosure(),
			JXWidget::kHElastic, JXWidget::kVElastic,
			0,0,10,10);
	assert (itsHeader != NULL);
	itsHeader->FitToEnclosure(kJTrue, kJTrue);

	itsHeader->ShareEditMenu(itsView);
	itsHeader->ShareSearchMenu(itsView);

	GMDirectorMenu* menu =
		new GMDirectorMenu(kWindowsMenuTitleStr, menuBar,
			JXWidget::kFixedLeft, JXWidget::kVElastic, 0,0, 10,10);
	assert(menu != NULL);
	menuBar->AppendMenu(menu);

	itsPrefsMenu = menuBar->AppendTextMenu(kPrefsMenuTitleStr);
	itsPrefsMenu->SetMenuItems(kPrefsMenuStr);
	itsPrefsMenu->SetUpdateAction(JXMenu::kDisableNone);
	ListenTo(itsPrefsMenu);

	itsHelpMenu = menuBar->AppendTextMenu(kHelpMenuTitleStr);
	itsHelpMenu->SetMenuItems(kHelpMenuStr);
	itsHelpMenu->SetUpdateAction(JXMenu::kDisableNone);
	ListenTo(itsHelpMenu);

	itsFileMenu->SetItemImage(kNewCmd, filenew);
	itsFileMenu->SetItemImage(kNewMBox, envelopes);
	itsFileMenu->SetItemImage(kOpenCmd, fileopen);
	itsFileMenu->SetItemImage(kSaveCmd, filefloppy);
	itsFileMenu->SetItemImage(kPrintCmd, fileprint);
	itsFileMenu->SetItemImage(kShowNextCmd, mini_right);
	itsFileMenu->SetItemImage(kDeleteShowNextCmd, mini_del_right);
	itsFileMenu->SetItemImage(kShowPrevCmd, mini_left);

	itsMessageMenu->SetItemImage(kDecryptCmd, unlock_xpm);
	itsMessageMenu->SetItemImage(kSaveAttachCmd, paperclip);
	itsMessageMenu->SetItemImage(kReplyCmd, reply_xpm);
	itsMessageMenu->SetItemImage(kReplySenderCmd, reply_sender_xpm);
	itsMessageMenu->SetItemImage(kReplyAllCmd, reply_all_xpm);
	itsMessageMenu->SetItemImage(kForwardCmd, forward_xpm);
	itsMessageMenu->SetItemImage(kRedirectCmd, redirect_xpm);

	itsHelpMenu->SetItemImage(kTOCCmd, jx_help_toc);
	itsHelpMenu->SetItemImage(kThisWindowCmd, JXPM(jx_help_specific));

	itsToolBar->LoadPrefs();

	if (itsToolBar->IsEmpty())
		{
		itsToolBar->AppendButton(itsFileMenu, kNewCmd);
		itsToolBar->AppendButton(itsFileMenu, kOpenCmd);
		itsToolBar->NewGroup();

		itsToolBar->AppendButton(itsFileMenu, kSaveCmd);
		itsToolBar->NewGroup();

		itsToolBar->AppendButton(itsFileMenu, kPrintCmd);
		itsToolBar->NewGroup();

		itsToolBar->AppendButton(itsFileMenu, kShowNextCmd);
		itsToolBar->AppendButton(itsFileMenu, kShowPrevCmd);
		itsToolBar->AppendButton(itsFileMenu, kDeleteShowNextCmd);
		itsToolBar->NewGroup();

		itsToolBar->AppendButton(itsMessageMenu, kReplyCmd);
		itsToolBar->AppendButton(itsMessageMenu, kReplySenderCmd);
		itsToolBar->AppendButton(itsMessageMenu, kReplyAllCmd);
		itsToolBar->AppendButton(itsMessageMenu, kForwardCmd);
		itsToolBar->AppendButton(itsMessageMenu, kRedirectCmd);
		}

	itsMenuIcon = new JXImage(window->GetDisplay(), jx_plain_file_small);
	assert(itsMenuIcon != NULL);
	itsMenuIcon->ConvertToRemoteStorage();
}
//---------------------------------------------------------------------------//
// Hex-8 test.
TEUCHOS_UNIT_TEST( STKMeshEntitySet, hex_8_test )
{
    // Extract the raw mpi communicator.
    Teuchos::RCP<const Teuchos::Comm<int> > comm = getDefaultComm<int>();
    Teuchos::RCP<const Teuchos::MpiComm<int> > mpi_comm = 
	Teuchos::rcp_dynamic_cast< const Teuchos::MpiComm<int> >( comm );
    Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > opaque_comm = 
	mpi_comm->getRawMpiComm();
    MPI_Comm raw_comm = (*opaque_comm)();

    // Create meta data.
    int space_dim = 3;
    stk::mesh::MetaData meta_data( space_dim );

    // Make two parts.
    std::string p1_name = "part_1";
    stk::mesh::Part& part_1 = meta_data.declare_part( p1_name );
    stk::mesh::set_topology( part_1, stk::topology::HEX_8 );
    int part_1_id = part_1.mesh_meta_data_ordinal();
    std::string p2_name = "part_2";
    stk::mesh::Part& part_2 = meta_data.declare_part( p2_name );
    int part_2_id = part_2.mesh_meta_data_ordinal();

    // Make a coordinate field.
    stk::mesh::Field<double, stk::mesh::Cartesian3d>& coord_field =
	meta_data.declare_field<
	stk::mesh::Field<double, stk::mesh::Cartesian3d> >(
	    stk::topology::NODE_RANK, "coordinates");
    meta_data.set_coordinate_field( &coord_field );
    stk::mesh::put_field( coord_field, part_1 );
    meta_data.commit();

    // Create bulk data.
    Teuchos::RCP<stk::mesh::BulkData> bulk_data =
	Teuchos::rcp( new stk::mesh::BulkData(meta_data,raw_comm) );
    bulk_data->modification_begin();

    // Make a hex-8.
    int comm_rank = comm->getRank();
    stk::mesh::EntityId hex_id = 23 + comm_rank;
    stk::mesh::Entity hex_entity = 
	bulk_data->declare_entity( stk::topology::ELEM_RANK, hex_id, part_1 );
    unsigned num_nodes = 8;
    Teuchos::Array<stk::mesh::EntityId> node_ids( num_nodes );
    Teuchos::Array<stk::mesh::Entity> nodes( num_nodes );
    for ( unsigned i = 0; i < num_nodes; ++i )
    {
	node_ids[i] = num_nodes*comm_rank + i + 5;
	nodes[i] = bulk_data->declare_entity( 
	    stk::topology::NODE_RANK, node_ids[i], part_1 );
	bulk_data->declare_relation( hex_entity, nodes[i], i );
    }
    bulk_data->modification_end();

    // Create the node coordinates.
    double* node_coords = 0;
    node_coords = stk::mesh::field_data( coord_field, nodes[0] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[1] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[2] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[3] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[4] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[5] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[6] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[7] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    // Create an entity set.
    Teuchos::RCP<DataTransferKit::EntitySet> entity_set =
	Teuchos::rcp( new DataTransferKit::STKMeshEntitySet(bulk_data) );

    // Test the set.
    Teuchos::RCP<const Teuchos::Comm<int> > set_comm = 
	entity_set->communicator();
    TEST_EQUALITY( set_comm->getRank(), comm->getRank() );
    TEST_EQUALITY( set_comm->getSize(), comm->getSize() );
    TEST_EQUALITY( space_dim, entity_set->physicalDimension() );

    // Make an iterator for the hex.
    std::function<bool(DataTransferKit::Entity)> all_pred = 
	[=] (DataTransferKit::Entity e){return true;};
    DataTransferKit::EntityIterator volume_iterator = 
	entity_set->entityIterator( space_dim, all_pred );

    // Test the volume iterator.
    TEST_EQUALITY( volume_iterator.size(), 1 );
    TEST_ASSERT( volume_iterator == volume_iterator.begin() );
    TEST_ASSERT( volume_iterator != volume_iterator.end() );

    // Test the volume under the iterator.
    TEST_EQUALITY( hex_id, volume_iterator->id() );
    TEST_EQUALITY( comm_rank, volume_iterator->ownerRank() );
    TEST_EQUALITY( space_dim, volume_iterator->topologicalDimension() );
    TEST_EQUALITY( space_dim, volume_iterator->physicalDimension() );
    TEST_ASSERT( volume_iterator->inBlock(part_1_id) );
    TEST_ASSERT( !volume_iterator->inBlock(part_2_id) );
    TEST_ASSERT( volume_iterator->onBoundary(part_1_id) );
    TEST_ASSERT( !volume_iterator->onBoundary(part_2_id) );

    Teuchos::RCP<DataTransferKit::EntityExtraData> extra_data_1 =
	volume_iterator->extraData();
    TEST_EQUALITY( hex_entity,
		   Teuchos::rcp_dynamic_cast<DataTransferKit::STKMeshEntityExtraData>(
		       extra_data_1)->d_stk_entity );

    Teuchos::Tuple<double,6> hex_bounds_1;
    volume_iterator->boundingBox( hex_bounds_1 );
    TEST_EQUALITY( 0.0, hex_bounds_1[0] );
    TEST_EQUALITY( 0.0, hex_bounds_1[1] );
    TEST_EQUALITY( 0.0, hex_bounds_1[2] );
    TEST_EQUALITY( 1.0, hex_bounds_1[3] );
    TEST_EQUALITY( 1.0, hex_bounds_1[4] );
    TEST_EQUALITY( 1.0, hex_bounds_1[5] );

    // Test the end of the iterator.
    volume_iterator++;
    TEST_ASSERT( volume_iterator != volume_iterator.begin() );
    TEST_ASSERT( volume_iterator == volume_iterator.end() );

    // Make an iterator for the nodes.
    DataTransferKit::EntityIterator node_iterator = 
	entity_set->entityIterator( 0, all_pred );

    // Test the node iterator.
    TEST_EQUALITY( node_iterator.size(), num_nodes );
    TEST_ASSERT( node_iterator == node_iterator.begin() );
    TEST_ASSERT( node_iterator != node_iterator.end() );
    DataTransferKit::EntityIterator node_begin = node_iterator.begin();
    DataTransferKit::EntityIterator node_end = node_iterator.end();
    auto node_id_it = node_ids.begin();
    for ( node_iterator = node_begin;
	  node_iterator != node_end;
	  ++node_iterator, ++node_id_it )
    {
	TEST_EQUALITY( node_iterator->id(), *node_id_it );
    }

    // Get each entity and check.
    DataTransferKit::Entity set_hex;
    entity_set->getEntity( hex_id, space_dim, set_hex );
    TEST_EQUALITY( set_hex.id(), hex_id );
    for ( unsigned i = 0; i < num_nodes; ++i )
    {
	DataTransferKit::Entity set_node;
	entity_set->getEntity( node_ids[i], 0, set_node );
	TEST_EQUALITY( set_node.id(), node_ids[i] );
    }

    // Check the adjacency function.
    Teuchos::Array<DataTransferKit::Entity> hex_adjacent_volumes;
    entity_set->getAdjacentEntities( set_hex,
				     space_dim,
				     hex_adjacent_volumes );
    TEST_EQUALITY( 0, hex_adjacent_volumes.size() );

    Teuchos::Array<DataTransferKit::Entity> hex_adjacent_nodes;
    entity_set->getAdjacentEntities( set_hex, 0, hex_adjacent_nodes );
    TEST_EQUALITY( num_nodes, hex_adjacent_nodes.size() );
    for ( unsigned i = 0; i < num_nodes; ++i )
    {
	TEST_EQUALITY( hex_adjacent_nodes[i].id(), node_ids[i] );
    }

    for ( unsigned i = 0; i < num_nodes; ++i )
    {
	Teuchos::Array<DataTransferKit::Entity> node_adjacent_volumes;
	entity_set->getAdjacentEntities( hex_adjacent_nodes[i],
					 space_dim,
					 node_adjacent_volumes );
	TEST_EQUALITY( 1, node_adjacent_volumes.size() );
	TEST_EQUALITY( node_adjacent_volumes[0].id(), hex_id );
    }
}
template <int dim> void update(grid<dim, sparse<phi_type> >& oldGrid, int steps)
{
	int rank=0;
	#ifdef MPI_VERSION
	rank=MPI::COMM_WORLD.Get_rank();
	#endif
	const phi_type dt = 0.01;
	const phi_type width = 14.5;
	const phi_type epsilon = 1.0e-8;
	const double mu_hi = 1.00;
	const double mu_lo = 0.01;
	const double mu_x = 0.6422;
	const double mu_s = 0.0175;

	std::ofstream vfile;
	if (rank==0)
		vfile.open("v.log",std::ofstream::out | std::ofstream::app);

	for (int step = 0; step < steps; step++) {
		if (rank==0) print_progress(step, steps);
		// newGrid grid must be overwritten each time
		ghostswap(oldGrid);
		grid<dim, sparse<phi_type> > newGrid(oldGrid);

		for (int d=0; d<dim; d++) {
			if (x0(oldGrid, d) == g0(oldGrid,d)) {
				b0(oldGrid,d) = Dirichlet;
				b0(newGrid,d) = Dirichlet;
			} else if (x1(oldGrid,d) == g1(oldGrid,d)) {
				b1(oldGrid,d) = Dirichlet;
				b1(newGrid,d) = Dirichlet;
			}
		}

		for (int i = 0; i < nodes(oldGrid); i++) {
			vector<int> x = position(oldGrid, i);

			// determine nonzero fields within
			// the neighborhood of this node
			// (2 adjacent voxels along each cardinal direction)
			sparse<int> s;
			for (int j = 0; j < dim; j++)
				for (int k = -1; k <= 1; k++) {
					x[j] += k;
					for (int h = 0; h < length(oldGrid(x)); h++) {
						int pindex = index(oldGrid(x), h);
						set(s, pindex) = 1;
					}
					x[j] -= k;
				}
			phi_type S = phi_type(length(s));

			// if only one field is nonzero,
			// then copy this node to newGrid
			if (S < 2.0) newGrid(i) = oldGrid(i);
			else {
				// compute laplacian of each field
				sparse<phi_type> lap = laplacian(oldGrid, i);

				// compute variational derivatives
				sparse<phi_type> dFdp;
				for (int h = 0; h < length(s); h++) {
					int hindex = index(s, h);
					for (int j = h + 1; j < length(s); j++) {
						int jindex = index(s, j);
						phi_type gamma = energy(hindex, jindex);
						phi_type eps = 4.0 / acos(-1.0) * sqrt(0.5 * gamma * width);
						phi_type w = 4.0 * gamma / width;
						// Update dFdp_h and dFdp_j, so the inner loop can be over j>h instead of j≠h
						set(dFdp, hindex) += 0.5 * eps * eps * lap[jindex] + w * oldGrid(i)[jindex];
						set(dFdp, jindex) += 0.5 * eps * eps * lap[hindex] + w * oldGrid(i)[hindex];
					}
				}

				// compute time derivatives
				sparse<phi_type> dpdt;
				phi_type mu = mobility(mu_lo, mu_hi, mu_x, mu_s, oldGrid(x).getMagPhi());

				for (int h = 0; h < length(s); h++) {
					int hindex = index(s, h);
					for (int j = h + 1; j < length(s); j++) {
						int jindex = index(s, j);
						set(dpdt, hindex) -= mu * (dFdp[hindex] - dFdp[jindex]);
						set(dpdt, jindex) -= mu * (dFdp[jindex] - dFdp[hindex]);
					}
				}

				// compute update values
				phi_type sum = 0.0;
				for (int h = 0; h < length(s); h++) {
					int pindex = index(s, h);
					phi_type value = oldGrid(i)[pindex] + dt * (2.0 / S) * dpdt[pindex]; // Extraneous factor of 2?
					if (value > 1.0) value = 1.0;
					if (value < 0.0) value = 0.0;
					if (value > epsilon) set(newGrid(i), pindex) = value;
					sum += newGrid(i)[pindex];
				}

				// project onto Gibbs simplex (enforce Σφ=1)
				phi_type rsum = 0.0;
				if (fabs(sum) > 0.0) rsum = 1.0 / sum;
				for (int h = 0; h < length(newGrid(i)); h++) {
					int pindex = index(newGrid(i), h);
					set(newGrid(i), pindex) *= rsum;
				}
			}

		} // Loop over nodes(oldGrid)

		if ((step+1) % 10 == 0) {
			// Scan along just above the mid-line for the grain boundary.
			// When found, determine its angle.
			vector<int> x(dim, 0);
			const int offset = 2;

			const phi_type vert_mag = 1.0/std::sqrt(3.0);
			const phi_type edge_mag = 1.0/std::sqrt(2.0);
			const phi_type bulk_mag = 1.0;

			const phi_type edge_contour = edge_mag + 0.125*(bulk_mag - edge_mag);
			const phi_type vert_contour = vert_mag + 0.125*(edge_mag - vert_mag);

			x[0] = x0(newGrid,0);
			x[1] = (g1(newGrid,1) - g0(newGrid,1))/2;
			while (x[0]<x1(newGrid) && x[1]>=y0(newGrid) && x[1]<y1(newGrid) && newGrid(x).getMagPhi()>vert_contour)
				x[0]++;
			if (x[0] == x1(newGrid))
				x[0] = g0(newGrid,0);
			int v0 = x[0];
			#ifdef MPI_VERSION
			MPI::COMM_WORLD.Allreduce(&x[0], &v0, 1, MPI_INT, MPI_MAX);
			#endif

			x[1] += offset;
			while (x[0]>= x0(newGrid) && x[0]<x1(newGrid) && x[1]>=y0(newGrid) && x[1]<y1(newGrid) && newGrid(x).getMagPhi()>edge_contour)
				x[0]++;
			if (x[0] == x1(newGrid))
				x[0] = g0(newGrid,0);
			int v1 = x[0];
			#ifdef MPI_VERSION
			MPI::COMM_WORLD.Allreduce(&x[0], &v1, 1, MPI_INT, MPI_MAX);
			#endif

			x[1] += offset;
			while (x[0]>= x0(newGrid) && x[0]<x1(newGrid) && x[1]>=y0(newGrid) && x[1]<y1(newGrid) && newGrid(x).getMagPhi()>edge_contour)
				x[0]++;
			if (x[0] == x1(newGrid))
				x[0] = g0(newGrid,0);
			int v2 = x[0];
			#ifdef MPI_VERSION
			MPI::COMM_WORLD.Allreduce(&x[0], &v2, 1, MPI_INT, MPI_MAX);
			#endif

			// Second-order right-sided difference to approximate slope
			double diffX = 3.0*v0 - 4.0*v1 + 1.0*v2;
			double theta = 180.0/M_PI * std::atan2(2.0*offset*dx(newGrid,1), dx(newGrid,0)*diffX);

			if (rank==0)
				vfile << dx(newGrid,0)*v0 << '\t' << dx(newGrid,0)*v1 << '\t' << dx(newGrid,0)*v2 << '\t' << diffX << '\t' << theta << '\n';
		}

		swap(oldGrid, newGrid);
	} // Loop over steps
	ghostswap(oldGrid);

	if (rank==0)
		vfile.close();
}
Beispiel #4
0
MeshLib::Mesh* VtkMeshConverter::convertUnstructuredGrid(
    vtkUnstructuredGrid* grid, std::string const& mesh_name)
{
    if (!grid)
        return nullptr;

    // set mesh nodes
    const std::size_t nNodes = grid->GetPoints()->GetNumberOfPoints();
    std::vector<MeshLib::Node*> nodes(nNodes);
    double* coords = nullptr;
    for (std::size_t i = 0; i < nNodes; i++)
    {
        coords = grid->GetPoints()->GetPoint(i);
        nodes[i] = new MeshLib::Node(coords[0], coords[1], coords[2]);
    }

    // set mesh elements
    const std::size_t nElems = grid->GetNumberOfCells();
    std::vector<MeshLib::Element*> elements(nElems);
    auto node_ids = vtkSmartPointer<vtkIdList>::New();
    for (std::size_t i = 0; i < nElems; i++)
    {
        MeshLib::Element* elem;
        grid->GetCellPoints(i, node_ids);

        int cell_type = grid->GetCellType(i);
        switch (cell_type)
        {
            case VTK_VERTEX:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Point>(
                    nodes, node_ids);
                break;
            }
            case VTK_LINE:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Line>(
                    nodes, node_ids);
                break;
            }
            case VTK_TRIANGLE:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Tri>(
                    nodes, node_ids);
                break;
            }
            case VTK_QUAD:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Quad>(
                    nodes, node_ids);
                break;
            }
            case VTK_PIXEL:
            {
                auto** quad_nodes = new MeshLib::Node*[4];
                quad_nodes[0] = nodes[node_ids->GetId(0)];
                quad_nodes[1] = nodes[node_ids->GetId(1)];
                quad_nodes[2] = nodes[node_ids->GetId(3)];
                quad_nodes[3] = nodes[node_ids->GetId(2)];
                elem = new MeshLib::Quad(quad_nodes);
                break;
            }
            case VTK_TETRA:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Tet>(
                    nodes, node_ids);
                break;
            }
            case VTK_HEXAHEDRON:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Hex>(
                    nodes, node_ids);
                break;
            }
            case VTK_VOXEL:
            {
                auto** voxel_nodes = new MeshLib::Node*[8];
                voxel_nodes[0] = nodes[node_ids->GetId(0)];
                voxel_nodes[1] = nodes[node_ids->GetId(1)];
                voxel_nodes[2] = nodes[node_ids->GetId(3)];
                voxel_nodes[3] = nodes[node_ids->GetId(2)];
                voxel_nodes[4] = nodes[node_ids->GetId(4)];
                voxel_nodes[5] = nodes[node_ids->GetId(5)];
                voxel_nodes[6] = nodes[node_ids->GetId(7)];
                voxel_nodes[7] = nodes[node_ids->GetId(6)];
                elem = new MeshLib::Hex(voxel_nodes);
                break;
            }
            case VTK_PYRAMID:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Pyramid>(
                    nodes, node_ids);
                break;
            }
            case VTK_WEDGE:
            {
                auto** prism_nodes = new MeshLib::Node*[6];
                for (unsigned i = 0; i < 3; ++i)
                {
                    prism_nodes[i] = nodes[node_ids->GetId(i + 3)];
                    prism_nodes[i + 3] = nodes[node_ids->GetId(i)];
                }
                elem = new MeshLib::Prism(prism_nodes);
                break;
            }
            case VTK_QUADRATIC_EDGE:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Line3>(
                    nodes, node_ids);
                break;
            }
            case VTK_QUADRATIC_TRIANGLE:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Tri6>(
                    nodes, node_ids);
                break;
            }
            case VTK_QUADRATIC_QUAD:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Quad8>(
                    nodes, node_ids);
                break;
            }
            case VTK_BIQUADRATIC_QUAD:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Quad9>(
                    nodes, node_ids);
                break;
            }
            case VTK_QUADRATIC_TETRA:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Tet10>(
                    nodes, node_ids);
                break;
            }
            case VTK_QUADRATIC_HEXAHEDRON:
            {
                elem = detail::createElementWithSameNodeOrder<MeshLib::Hex20>(
                    nodes, node_ids);
                break;
            }
            case VTK_QUADRATIC_PYRAMID:
            {
                elem =
                    detail::createElementWithSameNodeOrder<MeshLib::Pyramid13>(
                        nodes, node_ids);
                break;
            }
            case VTK_QUADRATIC_WEDGE:
            {
                auto** prism_nodes = new MeshLib::Node*[15];
                for (unsigned i = 0; i < 3; ++i)
                {
                    prism_nodes[i] = nodes[node_ids->GetId(i + 3)];
                    prism_nodes[i + 3] = nodes[node_ids->GetId(i)];
                }
                for (unsigned i = 0; i < 3; ++i)
                    prism_nodes[6 + i] = nodes[node_ids->GetId(8 - i)];
                prism_nodes[9] = nodes[node_ids->GetId(12)];
                prism_nodes[10] = nodes[node_ids->GetId(14)];
                prism_nodes[11] = nodes[node_ids->GetId(13)];
                for (unsigned i = 0; i < 3; ++i)
                    prism_nodes[12 + i] = nodes[node_ids->GetId(11 - i)];
                elem = new MeshLib::Prism15(prism_nodes);
                break;
            }
            default:
                ERR("VtkMeshConverter::convertUnstructuredGrid(): Unknown mesh "
                    "element type \"%d\".",
                    cell_type);
                return nullptr;
        }

        elements[i] = elem;
    }

    MeshLib::Mesh* mesh = new MeshLib::Mesh(mesh_name, nodes, elements);
    convertScalarArrays(*grid, *mesh);

    return mesh;
}
//---------------------------------------------------------------------------//
// Hex-8 test.
TEUCHOS_UNIT_TEST( STKMeshEntity, hex_8_test )
{
    // Extract the raw mpi communicator.
    Teuchos::RCP<const Teuchos::Comm<int> > comm = getDefaultComm<int>();
    Teuchos::RCP<const Teuchos::MpiComm<int> > mpi_comm = 
	Teuchos::rcp_dynamic_cast< const Teuchos::MpiComm<int> >( comm );
    Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > opaque_comm = 
	mpi_comm->getRawMpiComm();
    MPI_Comm raw_comm = (*opaque_comm)();

    // Create meta data.
    int space_dim = 3;
    stk::mesh::MetaData meta_data( space_dim );

    // Make two parts.
    std::string p1_name = "part_1";
    stk::mesh::Part& part_1 = meta_data.declare_part( p1_name );
    stk::mesh::set_topology( part_1, stk::topology::HEX_8 );
    int part_1_id = part_1.mesh_meta_data_ordinal();
    std::string p2_name = "part_2";
    stk::mesh::Part& part_2 = meta_data.declare_part( p2_name );
    int part_2_id = part_2.mesh_meta_data_ordinal();

    // Make a coordinate field.
    stk::mesh::Field<double, stk::mesh::Cartesian3d>& coord_field =
	meta_data.declare_field<
	stk::mesh::Field<double, stk::mesh::Cartesian3d> >(
	    stk::topology::NODE_RANK, "coordinates");
    meta_data.set_coordinate_field( &coord_field );
    stk::mesh::put_field( coord_field, part_1 );
    meta_data.commit();

    // Create bulk data.
    Teuchos::RCP<stk::mesh::BulkData> bulk_data =
	Teuchos::rcp( new stk::mesh::BulkData(meta_data,raw_comm) );
    bulk_data->modification_begin();

    // Make a hex-8.
    int comm_rank = comm->getRank();
    stk::mesh::EntityId hex_id = 23 + comm_rank;
    stk::mesh::Entity hex_entity = 
	bulk_data->declare_entity( stk::topology::ELEM_RANK, hex_id, part_1 );
    int num_nodes = 8;
    Teuchos::Array<stk::mesh::EntityId> node_ids( num_nodes );
    Teuchos::Array<stk::mesh::Entity> nodes( num_nodes );
    for ( int i = 0; i < num_nodes; ++i )
    {
	node_ids[i] = num_nodes*comm_rank + i + 5;
	nodes[i] = bulk_data->declare_entity( 
	    stk::topology::NODE_RANK, node_ids[i], part_1 );
	bulk_data->declare_relation( hex_entity, nodes[i], i );
    }
    bulk_data->modification_end();

    // Create the node coordinates.
    double* node_coords = 0;
    node_coords = stk::mesh::field_data( coord_field, nodes[0] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[1] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[2] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[3] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[4] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[5] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[6] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[7] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    // Create a DTK entity for the hex.
    DataTransferKit::Entity dtk_entity = 
	DataTransferKit::STKMeshEntity( hex_entity, bulk_data.ptr() );

    // Print out the entity.
    Teuchos::RCP<Teuchos::FancyOStream>
	fancy_out = Teuchos::VerboseObjectBase::getDefaultOStream();
    dtk_entity.describe( *fancy_out );
    
    // Test the entity.
    TEST_EQUALITY( hex_id, dtk_entity.id() );
    TEST_EQUALITY( comm_rank, dtk_entity.ownerRank() );
    TEST_EQUALITY( 3, dtk_entity.topologicalDimension() );
    TEST_EQUALITY( space_dim, dtk_entity.physicalDimension() );
    TEST_ASSERT( dtk_entity.inBlock(part_1_id) );
    TEST_ASSERT( !dtk_entity.inBlock(part_2_id) );
    TEST_ASSERT( dtk_entity.onBoundary(part_1_id) );
    TEST_ASSERT( !dtk_entity.onBoundary(part_2_id) );

    Teuchos::RCP<DataTransferKit::EntityExtraData> extra_data =
	dtk_entity.extraData();
    TEST_EQUALITY( hex_entity,
		   Teuchos::rcp_dynamic_cast<DataTransferKit::STKMeshEntityExtraData>(
		       extra_data)->d_stk_entity );

    Teuchos::Tuple<double,6> hex_bounds;
    dtk_entity.boundingBox( hex_bounds );
    TEST_EQUALITY( 0.0, hex_bounds[0] );
    TEST_EQUALITY( 0.0, hex_bounds[1] );
    TEST_EQUALITY( 0.0, hex_bounds[2] );
    TEST_EQUALITY( 1.0, hex_bounds[3] );
    TEST_EQUALITY( 1.0, hex_bounds[4] );
    TEST_EQUALITY( 1.0, hex_bounds[5] );
}
Beispiel #6
0
TransCFG::TransCFG(FuncId funcId,
                   const ProfData* profData,
                   const SrcDB& srcDB,
                   const TcaTransIDMap& jmpToTransID) {
    assert(profData);

    // add nodes
    for (auto tid : profData->funcProfTransIDs(funcId)) {
        assert(profData->transRegion(tid) != nullptr);
        // This will skip DV Funclets if they were already
        // retranslated w/ the prologues:
        if (!profData->optimized(profData->transSrcKey(tid))) {
            int64_t counter = profData->transCounter(tid);
            int64_t weight  = RuntimeOption::EvalJitPGOThreshold - counter;
            addNode(tid, weight);
        }
    }

    // add arcs
    for (TransID dstId : nodes()) {
        SrcKey dstSK = profData->transSrcKey(dstId);
        RegionDesc::BlockPtr dstBlock = profData->transRegion(dstId)->entry();
        const SrcRec* dstSR = srcDB.find(dstSK);
        FTRACE(5, "TransCFG: adding incoming arcs in dstId = {}\n", dstId);
        TransIDSet predIDs = findPredTrans(dstSR, jmpToTransID);
        for (auto predId : predIDs) {
            if (hasNode(predId)) {
                auto predPostConds =
                    profData->transRegion(predId)->blocks().back()->postConds();
                SrcKey predSK = profData->transSrcKey(predId);
                if (preCondsAreSatisfied(dstBlock, predPostConds) &&
                        predSK.resumed() == dstSK.resumed()) {
                    FTRACE(5, "TransCFG: adding arc {} -> {} ({} -> {})\n",
                           predId, dstId, showShort(predSK), showShort(dstSK));
                    addArc(predId, dstId, TransCFG::Arc::kUnknownWeight);
                }
            }
        }
    }

    // infer arc weights
    bool changed;
    do {
        changed = false;
        for (TransID tid : nodes()) {
            int64_t nodeWeight = weight(tid);
            if (inferredArcWeight(inArcs(tid),  nodeWeight)) changed = true;
            if (inferredArcWeight(outArcs(tid), nodeWeight)) changed = true;
        }
    } while (changed);

    // guess weight or non-inferred arcs
    for (TransID tid : nodes()) {
        for (auto arc : outArcs(tid)) {
            if (arc->weight() == Arc::kUnknownWeight) {
                arc->setGuessed();
                int64_t arcWgt = std::min(weight(arc->src()), weight(arc->dst())) / 2;
                arc->setWeight(arcWgt);
            }
        }
    }
}
Beispiel #7
0
unsigned long update_old(MMSP::grid<dim, sparse<float> >& grid, int steps, int nthreads)
{
#if (!defined MPI_VERSION) && ((defined CCNI) || (defined BGQ))
    std::cerr<<"Error: MPI is required for CCNI."<<std::endl;
    exit(1);
#endif
    unsigned long timer=0;
    int rank=0;
#ifdef MPI_VERSION
    rank=MPI::COMM_WORLD.Get_rank();
#endif
    const float dt = 0.01;
    const float width = 10.0;
    const float gamma = 1.0;
    const float eps = 4.0 / acos(-1.0) * sqrt(0.5 * gamma * width);
    const float w = 4.0 * gamma / width;
    const float mu = 1.0;
    const float epsilon = 1.0e-8;

#ifndef SILENT
    static int iterations = 1;
#ifdef DEBUG
    if (iterations==1 && rank==0)
        printf("CFL condition Co=%2.2f.\n", mu*eps*eps*dt/(dx(grid, 0)*dx(grid,0)));
#endif
#endif

#ifndef SILENT
    if (rank==0) print_progress(0, steps, iterations);
#endif

    for (int step = 0; step < steps; step++) {
        // update grid must be overwritten each time
        MMSP::grid<dim, sparse<float> > update(grid);
        ghostswap(grid);

        unsigned long comp_time=rdtsc();
        for (int i = 0; i < nodes(grid); i++) {
            vector<int> x = position(grid, i);

            // determine nonzero fields within
            // the neighborhood of this node
            // (2 adjacent voxels along each cardinal direction)
            sparse<int> s;
            for (int j = 0; j < dim; j++)
                for (int k = -1; k <= 1; k++) {
                    x[j] += k;
                    for (int h = 0; h < length(grid(x)); h++) {
                        int index = MMSP::index(grid(x), h);
                        set(s, index) = 1;
                    }
                    x[j] -= k;
                }
            float S = float(length(s));

            // if only one field is nonzero,
            // then copy this node to update
            if (S < 2.0) update(i) = grid(i);
            else {
                // compute laplacian of each field
                sparse<float> lap = laplacian(grid, i);

                // compute variational derivatives
                sparse<float> dFdp;
                for (int h = 0; h < length(s); h++) {
                    int hindex = MMSP::index(s, h);
                    for (int j = h + 1; j < length(s); j++) {
                        int jindex = MMSP::index(s, j);
                        // Update dFdp_h and dFdp_j, so the inner loop can be over j>h instead of j≠h
                        set(dFdp, hindex) += 0.5 * eps * eps * lap[jindex] + w * grid(i)[jindex];
                        set(dFdp, jindex) += 0.5 * eps * eps * lap[hindex] + w * grid(i)[hindex];
                    }
                }

                // compute time derivatives
                sparse<float> dpdt;
                for (int h = 0; h < length(s); h++) {
                    int hindex = MMSP::index(s, h);
                    for (int j = h + 1; j < length(s); j++) {
                        int jindex = MMSP::index(s, j);
                        set(dpdt, hindex) -= mu * (dFdp[hindex] - dFdp[jindex]);
                        set(dpdt, jindex) -= mu * (dFdp[jindex] - dFdp[hindex]);
                    }
                }

                // compute update values
                float sum = 0.0;
                for (int h = 0; h < length(s); h++) {
                    int index = MMSP::index(s, h);
                    float value = grid(i)[index] + dt * (2.0 / S) * dpdt[index]; // Extraneous factor of 2?
                    if (value > 1.0) value = 1.0;
                    if (value < 0.0) value = 0.0;
                    if (value > epsilon) set(update(i), index) = value;
                    sum += update(i)[index];
                }

                // project onto Gibbs simplex (enforce Σφ=1)
                float rsum = 0.0;
                if (fabs(sum) > 0.0) rsum = 1.0 / sum;
                for (int h = 0; h < length(update(i)); h++) {
                    int index = MMSP::index(update(i), h);
                    set(update(i), index) *= rsum;
                }
            }
        } // Loop over nodes(grid)
        swap(grid, update);
        comp_time=rdtsc()-comp_time;
        timer+=comp_time;
#ifndef SILENT
        if (rank==0) print_progress(step+1, steps, iterations);
#endif
    } // Loop over steps
    ghostswap(grid);
#ifndef SILENT
    ++iterations;
#endif
    return timer;
}
Beispiel #8
0
/*----------------------------------------------------------------------*
 | Create the spd system (public)                            mwgee 12/05|
 | Note that this is collective for ALL procs                           |
 *----------------------------------------------------------------------*/
Epetra_CrsMatrix* MOERTEL::Manager::MakeSPDProblem()
{
  // time this process
  Epetra_Time time(Comm());
  time.ResetStartTime();

  // check whether all interfaces are complete and integrated
  std::map<int,Teuchos::RCP<MOERTEL::Interface> >::iterator curr;
  for (curr=interface_.begin(); curr != interface_.end(); ++curr)
  {
    if (curr->second->IsComplete() == false)
    {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** interface " << curr->second->Id() << " is not Complete()\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
    }
    if (curr->second->IsIntegrated() == false)
    {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** interface " << curr->second->Id() << " is not integrated yet\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
    }
  }
  
  // check whether we have a problemmap_
  if (problemmap_==Teuchos::null)
  {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** No problemmap_ set\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
  }
  
  // check whether we have a constraintsmap_
  if (constraintsmap_==Teuchos::null)
  {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** onstraintsmap is NULL\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
  }
  
  // check for saddlemap_
  if (saddlemap_==Teuchos::null)
  {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** saddlemap_==NULL\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
  }

  // check for inputmatrix
  if (inputmatrix_==Teuchos::null)
  {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** No inputmatrix set\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
  }

  // check whether we have M and D matrices
  if (D_==Teuchos::null || M_==Teuchos::null)
  {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** Matrix M or D is NULL\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
  }
  
  // we need a map from lagrange multiplier dofs to primal dofs on the same node
  std::vector<MOERTEL::Node*> nodes(0);
  std::map<int,int> lm_to_dof;
  for (curr=interface_.begin(); curr!=interface_.end(); ++curr)
  {
	Teuchos::RCP<MOERTEL::Interface> inter = curr->second;
    inter->GetNodeView(nodes);
    for (int i=0; i<(int)nodes.size(); ++i)
    {
      if (!nodes[i]->Nlmdof()) 
        continue;
      const int* dof = nodes[i]->Dof();
      const int* lmdof = nodes[i]->LMDof();
      for (int j=0; j<nodes[i]->Nlmdof(); ++j)
      {
        //cout << "j " << j << " maps lmdof " << lmdof[j] << " to dof " << dof[j] << endl;
        lm_to_dof[lmdof[j]] = dof[j];
      }
    }
  }
  lm_to_dof_ = Teuchos::rcp(new std::map<int,int>(lm_to_dof)); // this is a very useful map for the moertel_ml_preconditioner
  /*
               _              _
              |               |
              |  Arr  Arn  Mr | 
         S =  |               |
              |  Anr  Ann  D  | 
              |
              |  MrT  D    0  |
              |_          _   |

               _           _
              |            |
              |  Arr  Arn  | 
         A =  |            |
              |  Anr  Ann  | 
              |_          _|
  
        1) Ann is square and we need it's Range/DomainMap annmap
        
               _         _
        WT =  |_ 0 Dinv _|

        2) Build WT (has rowmap/rangemap annmap and domainmap problemmap_)
             
               _    _
              |     |
              |  Mr | 
         B =  |     |
              |  D  | 
              |_   _|
  
        3) Build B (has rowmap/rangemap problemmap_ and domainmap annmap)
        
        4) Build I, the identity matrix with maps problemmap_,problemmap_);
        
  */    
  
  int err=0;
  //--------------------------------------------------------------------------
  // 1) create the rangemap of Ann
  std::vector<int> myanngids(problemmap_->NumMyElements());
  int count=0;
  std::map<int,int>::iterator intintcurr;
  for (intintcurr=lm_to_dof.begin(); intintcurr!=lm_to_dof.end(); ++intintcurr)
  {
    if (problemmap_->MyGID(intintcurr->second)==false) 
      continue;
    if ((int)myanngids.size()<=count) 
      myanngids.resize(myanngids.size()+50);
    myanngids[count] = intintcurr->second;
    ++count;
  }
  myanngids.resize(count);
    int numglobalelements;
  Comm().SumAll(&count,&numglobalelements,1);
  Epetra_Map* annmap = new Epetra_Map(numglobalelements,count,&myanngids[0],0,Comm());
  annmap_ = Teuchos::rcp(annmap);
  myanngids.clear();


  //--------------------------------------------------------------------------
  // 2) create WT
  Epetra_CrsMatrix* WT        = new Epetra_CrsMatrix(Copy,*annmap,1,false); 
  for (intintcurr=lm_to_dof.begin(); intintcurr!=lm_to_dof.end(); ++intintcurr)
  {
    int lmdof = intintcurr->first;
    int dof   = intintcurr->second;
    if (D_->MyGRID(lmdof)==false)
      continue;
    int lmlrid = D_->LRID(lmdof);
    int numentries;
    int* indices;
    double* values;
    err = D_->ExtractMyRowView(lmlrid,numentries,values,indices);
    if (err) cout << "D_->ExtractMyRowView returned err=" << err << endl;
    bool foundit = false;
    for (int j=0; j<numentries; ++j)
    {
      int gcid = D_->GCID(indices[j]);
      if (gcid<0) cout << "Cannot find gcid for indices[j]\n";
      //cout << "Proc " << Comm().MyPID() << " lmdof " << lmdof << " dof " << dof << " gcid " << gcid << " val " << values[j] << endl;
      if (gcid==dof)
      {
        double val = 1./values[j];
        err = WT->InsertGlobalValues(dof,1,&val,&dof);
        if (err<0) cout << "WT->InsertGlobalValues returned err=" << err << endl;
        foundit = true;
        break;
      }
    }
    if (!foundit)
    {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** Cannot compute inverse of D_\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      cout << "lmdof " << lmdof << " dof " << dof << endl;
      return NULL;
    }  
  }
  WT->FillComplete(*problemmap_,*annmap);  
  WT_ = Teuchos::rcp(WT);

  //--------------------------------------------------------------------------
  // 3) create B
  // create a temporary matrix with rowmap of the Ann block
  Epetra_CrsMatrix* tmp = new Epetra_CrsMatrix(Copy,*annmap,120);
  std::vector<int> newindices(100);
  for (intintcurr=lm_to_dof.begin(); intintcurr!=lm_to_dof.end(); ++intintcurr)
  {
    int lmdof = intintcurr->first;
    int dof   = intintcurr->second;
    if (D_->MyGRID(lmdof)==false)
      continue;
    int lmlrid = D_->LRID(lmdof);
    if (lmlrid<0) cout << "Cannot find lmlrid for lmdof\n";
    int numentries;
    int* indices;
    double* values;
    
    // extract and add values from D
    err = D_->ExtractMyRowView(lmlrid,numentries,values,indices);
    if (err) cout << "D_->ExtractMyRowView returned err=" << err << endl;
    if (numentries>(int)newindices.size()) newindices.resize(numentries);
    for (int j=0; j<numentries; ++j)
    {
      newindices[j] = D_->GCID(indices[j]);
      if (newindices[j]<0) cout << "Cannot find gcid for indices[j]\n";
    }
    //cout << "Inserting from D in row " << dof << " cols/val ";
    //for (int j=0; j<numentries; ++j) cout << newindices[j] << "/" << values[j] << " ";
    //cout << endl;
    err = tmp->InsertGlobalValues(dof,numentries,values,&newindices[0]);
    if (err) cout << "tmp->InsertGlobalValues returned err=" << err << endl;
  
    // extract and add values from M
    err = M_->ExtractMyRowView(lmlrid,numentries,values,indices);
    if (err) cout << "M_->ExtractMyRowView returned err=" << err << endl;
    if (numentries>(int)newindices.size()) newindices.resize(numentries);
    for (int j=0; j<numentries; ++j)
    {
      newindices[j] = M_->GCID(indices[j]);
      if (newindices[j]<0) cout << "Cannot find gcid for indices[j]\n";
    }
    //cout << "Inserting from M in row " << dof << " cols/val ";
    //for (int j=0; j<numentries; ++j) cout << newindices[j] << "/" << values[j] << " ";
    //cout << endl;
    err = tmp->InsertGlobalValues(dof,numentries,values,&newindices[0]);
    if (err) cout << "tmp->InsertGlobalValues returned err=" << err << endl;
  }
  tmp->FillComplete(*(problemmap_.get()),*annmap);

  // B is transposed of tmp
  EpetraExt::RowMatrix_Transpose* trans = new EpetraExt::RowMatrix_Transpose(false);
  Epetra_CrsMatrix* B = &(dynamic_cast<Epetra_CrsMatrix&>(((*trans)(const_cast<Epetra_CrsMatrix&>(*tmp)))));
  delete tmp; tmp = NULL;
  B_ = Teuchos::rcp(new Epetra_CrsMatrix(*B));
  newindices.clear();

  //--------------------------------------------------------------------------
  // 4) create I
  Epetra_CrsMatrix* I = MOERTEL::PaddedMatrix(*problemmap_,1.0,1);
  I->FillComplete(*problemmap_,*problemmap_);
  I_ = Teuchos::rcp(I);

  //--------------------------------------------------------------------------
  // 5) Build BWT = B * WT
  Epetra_CrsMatrix* BWT = MOERTEL::MatMatMult(*B,false,*WT,false,OutLevel()); 

  //--------------------------------------------------------------------------
  // 6) create CBT = (I-BWT)*A*W*BT
  Epetra_CrsMatrix* spdrhs = new Epetra_CrsMatrix(Copy,*problemmap_,10,false);
  MOERTEL::MatrixMatrixAdd(*BWT,false,-1.0,*spdrhs,0.0);
  MOERTEL::MatrixMatrixAdd(*I,false,1.0,*spdrhs,1.0);
  spdrhs->FillComplete();
  spdrhs->OptimizeStorage();
  spdrhs_ = Teuchos::rcp(spdrhs);
  
  Epetra_CrsMatrix* tmp1 = MOERTEL::MatMatMult(*inputmatrix_,false,*WT,true,OutLevel());
  Epetra_CrsMatrix* tmp2 = MOERTEL::MatMatMult(*tmp1,false,*B,true,OutLevel());   
  delete tmp1;
  Epetra_CrsMatrix* CBT  = MOERTEL::MatMatMult(*spdrhs,false,*tmp2,false,OutLevel());   
  delete tmp2;
  
  //--------------------------------------------------------------------------
  // 7) create spdmatrix_ = A - CBT - (CBT)^T
  spdmatrix_ = Teuchos::rcp(new Epetra_CrsMatrix(Copy,*problemmap_,10,false));
  MOERTEL::MatrixMatrixAdd(*inputmatrix_,false,1.0,*spdmatrix_,0.0);
  MOERTEL::MatrixMatrixAdd(*CBT,false,-1.0,*spdmatrix_,1.0);
  MOERTEL::MatrixMatrixAdd(*CBT,true,-1.0,*spdmatrix_,1.0);
  delete CBT; CBT = NULL;
  spdmatrix_->FillComplete(); 
  spdmatrix_->OptimizeStorage();

  //--------------------------------------------------------------------------
  // tidy up
  lm_to_dof.clear();
  delete trans; B = NULL;
  // time this process
  double t = time.ElapsedTime();
  if (OutLevel()>5 && Comm().MyPID()==0)
    cout << "MOERTEL (Proc 0): Construct spd system in " << t << " sec\n";

  return spdmatrix_.get();
}
void CubeTetMeshFactory::buildBlock(stk::ParallelMachine parallelMach,int xBlock,int yBlock,int zBlock,STK_Interface & mesh) const
{
   // grab this processors rank and machine size
   std::pair<int,int> sizeAndStartX = determineXElemSizeAndStart(xBlock,xProcs_,machRank_);
   std::pair<int,int> sizeAndStartY = determineYElemSizeAndStart(yBlock,yProcs_,machRank_);
   std::pair<int,int> sizeAndStartZ = determineZElemSizeAndStart(zBlock,zProcs_,machRank_);

   int myXElems_start = sizeAndStartX.first;
   int myXElems_end  = myXElems_start+sizeAndStartX.second;
   int myYElems_start = sizeAndStartY.first;
   int myYElems_end  = myYElems_start+sizeAndStartY.second;
   int myZElems_start = sizeAndStartZ.first;
   int myZElems_end  = myZElems_start+sizeAndStartZ.second;

   int totalXElems = nXElems_*xBlocks_;
   int totalYElems = nYElems_*yBlocks_;
   int totalZElems = nZElems_*zBlocks_;

   double deltaX = (xf_-x0_)/double(totalXElems);
   double deltaY = (yf_-y0_)/double(totalYElems);
   double deltaZ = (zf_-z0_)/double(totalZElems);
 
   std::vector<double> coord(3,0.0);

   // build the nodes
   for(int nx=myXElems_start;nx<myXElems_end+1;++nx) {
      coord[0] = double(nx)*deltaX+x0_;
      for(int ny=myYElems_start;ny<myYElems_end+1;++ny) {
         coord[1] = double(ny)*deltaY+y0_;
         for(int nz=myZElems_start;nz<myZElems_end+1;++nz) {
            coord[2] = double(nz)*deltaZ+z0_;

            mesh.addNode(nz*(totalYElems+1)*(totalXElems+1)+ny*(totalXElems+1)+nx+1,coord);
         }
      }
   }

   std::stringstream blockName;
   blockName << "eblock-" << xBlock << "_" << yBlock << "_" << zBlock;
   stk::mesh::Part * block = mesh.getElementBlockPart(blockName.str());

   // build the elements
   for(int nx=myXElems_start;nx<myXElems_end;++nx) {
      for(int ny=myYElems_start;ny<myYElems_end;++ny) {
         for(int nz=myZElems_start;nz<myZElems_end;++nz) {

            std::vector<stk::mesh::EntityId> nodes(8);
            nodes[0] = nx+1+ny*(totalXElems+1) +nz*(totalYElems+1)*(totalXElems+1);
            nodes[1] = nodes[0]+1;              
            nodes[2] = nodes[1]+(totalXElems+1);
            nodes[3] = nodes[2]-1;              
            nodes[4] = nodes[0]+(totalYElems+1)*(totalXElems+1);
            nodes[5] = nodes[1]+(totalYElems+1)*(totalXElems+1);
            nodes[6] = nodes[2]+(totalYElems+1)*(totalXElems+1);
            nodes[7] = nodes[3]+(totalYElems+1)*(totalXElems+1);
   
            buildTetsOnHex(Teuchos::tuple(totalXElems,totalYElems,totalZElems), 
                           Teuchos::tuple(nx,ny,nz), 
                           block,nodes,mesh);
         }
      }
   }
}
Beispiel #10
0
void StitchHoles::stitchHole(QList<vtkIdType> loop_nodes)
{
  EG_VTKSP(vtkPolyData, edge_pdata);
  EG_VTKSP(vtkPoints, points);
  EG_VTKSP(vtkCellArray, polys);
  for (int i = 0; i < loop_nodes.size(); ++i) {
    vec3_t x;
    m_Grid->GetPoint(loop_nodes[i], x.data());
    x = toPlane(x);
    points->InsertNextPoint(x.data());
  }
  EG_VTKSP(vtkIdList, pts);
  pts->SetNumberOfIds(loop_nodes.size());
  for (vtkIdType i = 0; i < pts->GetNumberOfIds(); ++i) {
    pts->SetId(i, i);
  }
  polys->InsertNextCell(pts);
  edge_pdata->SetPoints(points);
  edge_pdata->SetPolys(polys);
  EG_VTKSP(vtkUnstructuredGrid, tri_grid);
  /*
  {
    QString name = GuiMainWindow::pointer()->getCwd() + "/input.vtk";
    EG_VTKSP(vtkPolyDataWriter, vtk);
    vtk->SetFileName(qPrintable(name));
    vtk->SetInputData(edge_pdata);
    vtk->Write();
  }
  */
  triangulate(edge_pdata, tri_grid, m_Bc);
  //writeGrid(tri_grid, "tri");
  gridFromPlane(tri_grid);

  EG_FORALL_CELLS(id_cell, tri_grid) {
    if (cellNormal(tri_grid, id_cell)*m_N < 0) {
      vtkIdType num_pts, *pts;
      tri_grid->GetCellPoints(id_cell, num_pts, pts);
      QVector<vtkIdType> nodes(num_pts);
      for (vtkIdType j = 0; j < num_pts; ++j) {
        nodes[j] = pts[j];
      }
      for (vtkIdType j = 0; j < num_pts; ++j) {
        pts[num_pts - j - 1] = nodes[j];
      }
    }
  }

  MeshPartition tri_part(tri_grid, true);
  /*
  int n1 = tri_grid->GetNumberOfPoints();
  int n2 = tri_grid->GetNumberOfCells();
  writeGrid(m_Grid, "before");
  */
  m_Part.addPartition(tri_part);
  /*
  int N1 = m_Grid->GetNumberOfPoints();
  int N2 = m_Grid->GetNumberOfCells();
  writeGrid(m_Grid, "after");
  */

  DeleteStrayNodes del_stray;
  del_stray.setGrid(m_Grid);
  del_stray.setAllCells();
  del_stray();
}
Beispiel #11
0
	void* thread_search(void * arg) {

		int id = thread_id.fetch_add(1);
		// closed list is waaaay too big for my computer.
		// original 512927357
		// TODO: Must optimize these numbers
		//  9999943
		// 14414443
		//129402307
//		HashTable<typename D::PackedState, Node> closed(512927357 / tnum);
		HashTable<typename D::PackedState, Node> closed(closedlistsize);

//	printf("closedlistsize = %u\n", closedlistsize);

//		Heap<Node> open(100, overrun);
		heap open(openlistsize, overrun);
		Pool<Node> nodes(2048);

		// If the buffer is locked when the thread pushes a node,
		// stores it locally and pushes it afterward.
		// TODO: Array of dynamic sized objects.
		// This array would be allocated in heap rather than stack.
		// Therefore, not the best optimized way to do.
		// Also we need to fix it to compile in clang++.
		std::vector<std::vector<Node*>> outgo_buffer;
		outgo_buffer.reserve(tnum);

		std::vector<Node*> tmp;
		tmp.reserve(10); // TODO: ad hoc random number

		uint expd_here = 0;
		uint gend_here = 0;
		int max_outgo_buffer_size = 0;
		int max_income_buffer_size = 0;

		unsigned int discarded_here = 0;
		int duplicate_here = 0;

		int current_f = 0;

		double lapse;

		int useless = 0;

		int fval = -1;

		// How many of the nodes sent to itself.
		// If this high, then lower communication overhead.
		unsigned int self_push = 0;

		//		while (path.size() == 0) {

		printf("id = %d\n", id);
		printf("incumbent = %d\n", incumbent.load());
		unsigned int over_incumbent_count = 0;
		unsigned int no_work_iteration = 0;

		double init_time = walltime();

		while (true) {
			Node *n;

			if (this->isTimed) {
				double t = walltime() - init_time;
//				printf("t = %f\n", t);
				if (t > this->timer) {
//					closed.destruct_all(nodes);
					terminate[id] = true;
					break;
				}
			}


#ifdef ANALYZE_LAP
			startlapse(lapse); // income buffer
#endif
			if (!income_buffer[id].isempty()) {
				terminate[id] = false;
				if (income_buffer[id].size() >= income_threshold) {
					++force_income;
					income_buffer[id].lock();
					tmp = income_buffer[id].pull_all_with_lock();
					income_buffer[id].release_lock();
					uint size = tmp.size();
#ifdef ANALYZE_INCOME
					if (max_income_buffer_size < size) {
						max_income_buffer_size = size;
					}
					dbgprintf("size = %d\n", size);
#endif // ANALYZE_INCOME
					for (int i = 0; i < size; ++i) {
						dbgprintf("pushing %d, ", i);
						open.push(tmp[i]); // Not sure optimal or not. Vector to Heap.
					}
					tmp.clear();
				} else if (income_buffer[id].try_lock()) {
					tmp = income_buffer[id].pull_all_with_lock();
//					printf("%d", __LINE__);
					income_buffer[id].release_lock();

					uint size = tmp.size();
#ifdef ANALYZE_INCOME
					if (max_income_buffer_size < size) {
						max_income_buffer_size = size;
					}
					dbgprintf("size = %d\n", size);
#endif // ANALYZE_INCOME
					for (int i = 0; i < size; ++i) {
						dbgprintf("pushing %d, ", i);
						open.push(tmp[i]); // Not sure optimal or not.
					}
					tmp.clear();
				}
			}
#ifdef ANALYZE_LAPSE
			endlapse(lapse, "incomebuffer");
			startlapse(&lapse); // open list
#endif
#ifdef OUTSOURCING
			open_sizes[id] = open.getsize();
#endif
			if (open.isemptyunder(incumbent.load())) {
				dbgprintf("open is empty.\n");
				terminate[id] = true;
				if (hasterminated() && incumbent != initmaxcost) {
					printf("terminated\n");
					break;
				}
				++no_work_iteration;
				for (int i = 0; i < tnum; ++i) {
					if (i != id && outgo_buffer[i].size() > 0) {
						if (income_buffer[i].try_lock()) {
							// acquired lock
							income_buffer[i].push_all_with_lock(
									outgo_buffer[i]);
							income_buffer[i].release_lock();
							outgo_buffer[i].clear();
						}
					}
				}
				continue; // ad hoc
			}
			n = static_cast<Node*>(open.pop());

//			if (n->f >= incumbent.load()) {
//				printf("open list error: n->f >= incumbent: %u > %d\n", n->f, incumbent.load());
//			}
//			printf("f,g = %d, %d\n", n->f, n->g);

#ifdef ANALYZE_LAPSE
			endlapse(lapse, "openlist");
#endif

#ifdef ANALYZE_FTRACE
			int newf = open.minf();
			Logfvalue* lg = new Logfvalue(walltime() - wall0, n->f, n->f - n->g);
			logfvalue[id].push_back(*lg);
			if (fvalues[id] != newf) {
//				printf("ftrace %d %d %f\n", id, fvalues[id],
//						walltime() - wall0);
				fvalues[id] = newf;
			}
#endif // ANALYZE_FTRACE
			// TODO: Might not be the best way.
			// Would there be more novel way?

#ifdef ANALYZE_GLOBALF
			if (n->f != fvalues[id]) {
				fvalues[id] = n->f;
				int min = *std::min_element(fvalues, fvalues+tnum);

				if (min != globalf) {
					globalf = min;
					printf("globalf %d %d %f\n", id, min, walltime() - wall0);
				}
			}
#endif

			// If the new node n is duplicated and
			// the f value is higher than or equal to the duplicate, discard it.
#ifdef ANALYZE_LAPSE
			startlapse(&lapse); // closed list
#endif
//		if (n->thrown == 0) {
			Node *duplicate = closed.find(n->packed);
			if (duplicate) {
				if (duplicate->f <= n->f) {
					dbgprintf("Discarded\n");
					++discarded_here;
					nodes.destruct(n);
					continue;
#ifdef ANALYZE_DUPLICATE
				} else {
					duplicate_here++;
#endif // ANALYZE_DUPLICATE
				}
				// Node access here is unnecessary duplicates.
//					printf("Duplicated\n");
			}
			//	}
#ifdef ANALYZE_LAPSE
			endlapse(lapse, "closedlist");
#endif

#ifdef OUTSOURCING
			if ((n->thrown < 5) && (expd_here > 600) && outsourcing(n, id)) {
				if (n->thrown == 0) {
					closed.add(n);
				}
#ifdef ANALYZE_OUTSOURCING
				outsource_pushed++;
#endif
				dbgprintf("Out sourced a node\n");
				continue;
			}
#endif // OUTSOURCING
			typename D::State state;
			this->dom.unpack(state, n->packed);

#ifdef ANALYZE_ORDER
			if (fval != n->f) {
				fval = n->f;
				LogNodeOrder* ln = new LogNodeOrder(globalOrder.fetch_add(1),
						state.sequence, fval, open.getsize());
				lognodeorder[id].push_back(*ln);
			} else {
				LogNodeOrder* ln = new LogNodeOrder(globalOrder.fetch_add(1),
						state.sequence, -1, open.getsize());
				lognodeorder[id].push_back(*ln);
			}
#endif // ANALYZE_ORDER
			if (this->dom.isgoal(state)) {
				// TODO: For some reason, sometimes pops broken node.
//				if (state.tiles[1] == 0) {
//					printf("isgoal ERROR\n");
//					continue;
//				}
//				print_state(state);

				std::vector<typename D::State> newpath;

				for (Node *p = n; p; p = p->parent) {
					typename D::State s;
					this->dom.unpack(s, p->packed);
					newpath.push_back(s); // This triggers the main loop to terminate.
				}
				int length = newpath.size();
				printf("Goal! length = %d\n", length);
				printf("cost = %u\n", n->g);

				if (incumbent > n->g) {
					// TODO: this should be changed to match non-unit cost domains.
					incumbent = n->g;
					LogIncumbent* li = new LogIncumbent(walltime() - wall0,
							incumbent);
					logincumbent[id].push_back(*li);
					path = newpath;
				}

				continue;
			}
#ifdef OUTSOURCING
			if (n->thrown == 0) {
				closed.add(n);
			}
#else
			closed.add(n);
#endif
			expd_here++;
//			if (expd_here % 100000 == 0) {
//				printf("expd: %u\n", expd_here);
//			}
			//		printf("expd: %d\n", id);

#ifdef ANALYZE_LAPSE
			startlapse(&lapse);
#endif

//			buffer<Node>* buffers;

			useless += uselessCalc(useless);

			for (int i = 0; i < this->dom.nops(state); i++) {
				// op is the next blank position.
				int op = this->dom.nthop(state, i);
//				if (op == n->pop) {
//					//					printf("erase %d \n", i);
//					continue;
//				}

//				printf("gend: %d\n", id);

//				int moving_tile = 0;
//				int blank = 0; // Make this available for Grid pathfinding.
//				int moving_tile = state.tiles[op];
//				int blank = state.blank; // Make this available for Grid pathfinding.
				Edge<D> e = this->dom.apply(state, op);
				Node* next = wrap(state, n, e.cost, e.pop, nodes);

				///////////////////////////
				/// TESTS
				/// Compare nodes, n & next
				/// 1. f value does increase (or same)
				/// 2. g increases by cost
				///
				/// Compare states
				/// 1. operation working fine
				///////////////////////////
				if (n->f > next->f) {
//					// heuristic was calculating too big.
					printf("!!!ERROR: f decreases: %u %u\n", n->f, next->f);
					unsigned int nh = n->f - n->g;
					unsigned int nxh = next->f - next->g;
					printf("h = %u %u\n", nh, nxh);
					printf("cost = %d\n", e.cost);
				}
//				if (static_cast<unsigned int>(n->g + e.cost) != static_cast<unsigned int>(next->g)) {
//					printf("!!!ERROR: g is wrong: %u + %d != %u\n", n->g, e.cost, next->g);
//				}

				if (next->f >= incumbent.load()) {
//					printf("needless\n");-
					++over_incumbent_count;
					nodes.destruct(next);
					this->dom.undo(state, e);
//					printf("%u >= %d\n", next->f, incumbent.load());
					continue;
				}
//				Node *duplicate = closed.find(next->packed);
//				if (duplicate) {
//					if (duplicate->f <= next->f) {
//						dbgprintf("Discarded\n");
//						++discarded_here;
//						nodes.destruct(next);
//						this->dom.undo(state, e);
//						continue;
//					} else {
//						++duplicate_here;
//					}
//				}
//				printf("inc: %d, inc.load: %d\n", incumbent.load());

//				if (next->f >= initmaxcost || next->g >= initmaxcost
//						|| next->f >= incumbent || next->g >= incumbent
//						|| next->f >= incumbent.load()
//						|| next->g >= incumbent.load()) {
//					printf("f >= initmaxcost: %d > %d\n", next->f, initmaxcost);
//				}

				gend_here++;
//				if (gend_here % 1000000 == 0) {
//					printf("gend: %u\n", gend_here);
////					printf("%u < %d\n", next->f, incumbent.load());
//				}
				//printf("mv blank op = %d %d %d \n", moving_tile, blank, op);
//				print_state(state);


				unsigned int zbr = z.inc_hash(n->zbr, 0, 0, op, 0, state);
				next->zbr = zbr;
				zbr = zbr % tnum;
//				next->zbr = z.inc_hash(n->zbr, moving_tile, blank, op,
//						0, state);

//				next->zbr = z.inc_hash(state);

//				unsigned int zbr = next->zbr % tnum;
//				printf("zbr, zbr_tnum = (%u, %u)\n", next->zbr, zbr);

				// If the node belongs to itself, just push to this open list.
				if (zbr == id) {
//					double w = walltime();
					++self_push;
					open.push(next);
//					printf("self: %f\n", walltime() - w);
//				}
#ifdef SEMISYNC
					// Synchronous communication to avoid search overhead
					else if (outgo_buffer[zbr].size() > outgo_threshold) {
						income_buffer[zbr].lock();
						income_buffer[zbr].push_with_lock(next);
						income_buffer[zbr].push_all_with_lock(outgo_buffer[zbr]);
//					printf("%d", __LINE__);
						income_buffer[zbr].release_lock();
						outgo_buffer[zbr].clear();
#ifdef ANALYZE_SEMISYNC
						++force_outgo;
//					printf("semisync = %d to %d\n", id, zbr);
#endif // ANALYZE_SEMISYNC
					}
#endif // SEMISYNC
//				else if (income_buffer[zbr].try_lock()) {
//					// if able to acquire the lock, then push all nodes in local buffer.
//					income_buffer[zbr].push_with_lock(next);
//					if (outgo_buffer[zbr].size() != 0) {
//						income_buffer[zbr].push_all_with_lock(
//								outgo_buffer[zbr]);
//					}
////					printf("%d", __LINE__);
//					income_buffer[zbr].release_lock();
//					outgo_buffer[zbr].clear();

				} else {
Beispiel #12
0
/// Transfer to the geometric mesh
void TPZFracSet::ToGeoMesh()
{
    fgmesh.CleanUp();
    fgmesh.NodeVec() = fNodeVec;
    int64_t nfrac = fFractureVec.NElements();
    for (int64_t ifr = 0; ifr < nfrac; ifr++) {
        TPZManVector<int64_t,2> nodes(2);
        nodes = fFractureVec[ifr].fNodes;
        int64_t index;
        fgmesh.CreateGeoElement(EOned, nodes, fFractureVec[ifr].fMatId, index);
    }
    fgmesh.BuildConnectivity();
    
    int64_t nel = fgmesh.NElements();
    for (int64_t el=0; el<nel; el++) {
        TPZGeoEl *gel = fgmesh.Element(el);
        if(!gel) continue;
        if (gel->Neighbour(2).Element() != gel) {
            std::cout << "gel index " << el << " is overlapping with " << gel->Neighbour(2).Element()->Index() << std::endl;
            TPZGeoEl *neigh = gel->Neighbour(2).Element();
            int matid = min(gel->MaterialId(),neigh->MaterialId());
            if(gel->MaterialId() == neigh->MaterialId())
            {
                matid = gel->MaterialId();
            }
            else if(gel->MaterialId() == matid_BC || neigh->MaterialId() == matid_BC)
            {
                matid = matid_BC;
            }
            else if((gel->MaterialId() == matid_internal_frac && neigh->MaterialId() == matid_MHM_line) ||
                (gel->MaterialId() == matid_MHM_line && neigh->MaterialId() == matid_internal_frac))
            {
                matid = matid_MHM_frac;
            }
            else
            {
                DebugStop();
            }
            gel->SetMaterialId(matid);
            neigh->SetMaterialId(matid);
            // remove the element with the lowest index
            if (gel->Index() > neigh->Index())
            {
                // delete neigh
                neigh->RemoveConnectivities();
                int64_t neighindex = neigh->Index();
                delete neigh;
                fgmesh.ElementVec()[neighindex] = 0;
                std::string matname = fFractureVec[neighindex].fPhysicalName;
                fFractureVec[gel->Index()].fPhysicalName = matname + "_MHM";
            }
            else
            {
                gel->RemoveConnectivities();
                std::string matname = fFractureVec[gel->Index()].fPhysicalName;
                fFractureVec[neigh->Index()].fPhysicalName = matname + "_MHM";
                delete gel;
                fgmesh.ElementVec()[el] = 0;
            }
        }
        
    }
}
Beispiel #13
0
/// add the cornernodes of the MHM mesh
void TPZFracSet::AddMHMNodes()
{
    int64_t nfrac = fFractureVec.NElements();
    int numx = (fTopRight[0]-fLowLeft[0])/fMHMSpacing[0];
    int numy = (fTopRight[1]-fLowLeft[1])/fMHMSpacing[1];
    for (int i=0; i<=numx; i++) {
        for (int j=0; j<=numy; j++) {
            TPZManVector<REAL,3> co(3,0.);
            co[0] = fLowLeft[0]+i*fMHMSpacing[0];
            co[1] = fLowLeft[1]+j*fMHMSpacing[1];
            TPZGeoNode node;
            node.SetCoord(co);
            int64_t index = InsertNode(node);
            fNodeVec[index].GetCoordinates(co);
            std::pair<uint32_t, uint32_t> p1 = NodeKey(co);
            if (p1.first % fMHMSpacingInt[0] != 0 || p1.second%fMHMSpacingInt[1] != 0) {
                DebugStop();
            }
        }
    }
    // build the datastructure for horizontal and vertical lines
    fHorizontalLines.Resize(numy+1);
    fVerticalLines.Resize(numx+1);
    int64_t nnodes = fNodeVec.NElements();
    for (int64_t in=0; in<nnodes; in++) {
        TPZManVector<REAL,3> co(3);
        fNodeVec[in].GetCoordinates(co);
        uint64_t locprev = GetLoc(fNodeVec[in]);
        std::pair<uint32_t, uint32_t> p1 = NodeKey(co);
        if (p1.first%fMHMSpacingInt[0] == 0) {
            int line = p1.first/fMHMSpacingInt[0];
            REAL coprev = fNodeVec[in].Coord(0);
            REAL conew = line*fTol*fMHMSpacingInt[0];
            fNodeVec[in].SetCoord(0, conew);
            uint64_t locafter = GetLoc(fNodeVec[in]);
            if (locprev != locafter) {
                DebugStop();
            }
            fVerticalLines[line][co[1]] = in;
        }
        if (p1.second%fMHMSpacingInt[1] == 0) {
            int line = p1.second/fMHMSpacingInt[1];
            REAL coprev = fNodeVec[in].Coord(1);
            REAL conew = line*fTol*fMHMSpacingInt[1];
            fNodeVec[in].SetCoord(1, conew);
            uint64_t locafter = GetLoc(fNodeVec[in]);
            if (locprev != locafter) {
                DebugStop();
            }
            fHorizontalLines[line][co[0]] = in;
        }
    }
    
    int64_t nhor = fHorizontalLines.NElements();
    for (int64_t hor = 0; hor < nhor; hor++) {
        for (auto it = fHorizontalLines[hor].begin(); it != fHorizontalLines[hor].end(); it++) {
            auto it2 = it;
            it2++;
            if (it2 == fHorizontalLines[hor].end()) {
                continue;
            }
            TPZManVector<int64_t,2> nodes(2);
            nodes[0] = it->second;
            nodes[1] = it2->second;
            int64_t index;
            int matid = matid_MHM_line;
            if (hor == 0 || hor == nhor-1) {
                matid = matid_BC;
            }
            TPZFracture frac = TPZFracture(nfrac++, matid, nodes[0], nodes[1]);
            frac.fFracPerm = 0;
            frac.fPhysicalName="MHMLine";
            if (hor == 0 || hor == nhor-1) {
                frac.fPhysicalName = "BC";
            }
            index  = fFractureVec.AllocateNewElement();
            fFractureVec[index] = frac;
        }
    }
    int64_t nver = fVerticalLines.NElements();
    for (int64_t ver = 0; ver < nver; ver++) {
        for (auto it = fVerticalLines[ver].begin(); it != fVerticalLines[ver].end(); it++) {
            auto it2 = it;
            it2++;
            if (it2 == fVerticalLines[ver].end()) {
                continue;
            }
            TPZManVector<int64_t,2> nodes(2);
            nodes[0] = it->second;
            nodes[1] = it2->second;
            int matid = matid_MHM_line;
            if (ver==0 || ver==nver-1) {
                matid = matid_BC;
            }
            int64_t index;
            TPZFracture frac = TPZFracture(nfrac++, matid, nodes[0], nodes[1]);
            frac.fFracPerm = 0.;
            frac.fPhysicalName = "MHMLine";
            if (ver == 0 || ver == nver-1) {
                frac.fPhysicalName = "BC";
            }
            index  = fFractureVec.AllocateNewElement();
            fFractureVec[index] = frac;
        }
    }

}
void Consensus::findConsensus(const vector<Point2f> & points, const vector<int> & classes,
        const float scale, const float rotation,
        Point2f & center, vector<Point2f> & points_inlier, vector<int> & classes_inlier)
{
    FILE_LOG(logDEBUG) << "Consensus::findConsensus() call";

    //If no points are available, reteurn nan
    if (points.size() == 0)
    {
        center.x = numeric_limits<float>::quiet_NaN();
        center.y = numeric_limits<float>::quiet_NaN();

        FILE_LOG(logDEBUG) << "Consensus::findConsensus() return";

        return;
    }

    //Compute votes
    vector<Point2f> votes(points.size());
    for (size_t i = 0; i < points.size(); i++)
    {
        votes[i] = points[i] - scale * rotate(points_normalized[classes[i]], rotation);
    }

    t_index N = points.size();

    float * D = new float[N*(N-1)/2]; //This is a lot of memory, so we put it on the heap
    cluster_result Z(N-1);

    //Compute pairwise distances between votes
    int index = 0;
    for (size_t i = 0; i < points.size(); i++)
    {
        for (size_t j = i+1; j < points.size(); j++)
        {
            //TODO: This index calculation is correct, but is it a good thing?
            //int index = i * (points.size() - 1) - (i*i + i) / 2 + j - 1;
            D[index] = norm(votes[i] - votes[j]);
            index++;
        }
    }

    FILE_LOG(logDEBUG) << "Consensus::MST_linkage_core() call";
    MST_linkage_core(N,D,Z);
    FILE_LOG(logDEBUG) << "Consensus::MST_linkage_core() return";

    union_find nodes(N);

    //Sort linkage by distance ascending
    std::stable_sort(Z[0], Z[N-1]);

    //S are cluster sizes
    int * S = new int[2*N-1];
    //TODO: Why does this loop go to 2*N-1? Shouldn't it be simply N? Everything > N gets overwritten later
    for(int i = 0; i < 2*N-1; i++)
    {
        S[i] = 1;
    }

    t_index parent = 0; //After the loop ends, parent contains the index of the last cluster
    for (node const * NN=Z[0]; NN!=Z[N-1]; ++NN)
    {
        // Get two data points whose clusters are merged in step i.
        // Find the cluster identifiers for these points.
        t_index node1 = nodes.Find(NN->node1);
        t_index node2 = nodes.Find(NN->node2);

        // Merge the nodes in the union-find data structure by making them
        // children of a new node
        // if the distance is appropriate
        if (NN->dist < thr_cutoff)
        {
            parent = nodes.Union(node1, node2);
            S[parent] = S[node1] + S[node2];
        }
    }

    //Get cluster labels
    int * T = new int[N];
    for (t_index i = 0; i < N; i++)
    {
        T[i] = nodes.Find(i);
    }

    //Find largest cluster
    int S_max = distance(S, max_element(S, S + 2*N-1));

    //Find inliers, compute center of votes
    points_inlier.reserve(S[S_max]);
    classes_inlier.reserve(S[S_max]);
    center.x = center.y = 0;

    for (size_t i = 0; i < points.size(); i++)
    {
        //If point is in consensus cluster
        if (T[i] == S_max)
        {
            points_inlier.push_back(points[i]);
            classes_inlier.push_back(classes[i]);
            center.x += votes[i].x;
            center.y += votes[i].y;
        }

    }

    center.x /= points_inlier.size();
    center.y /= points_inlier.size();

    delete[] D;
	delete[] S;
	delete[] T;

    FILE_LOG(logDEBUG) << "Consensus::findConsensus() return";
}
Beispiel #15
0
 bool ends_have_same_location() const {
     return nodes().ends_have_same_location();
 }
void CubeTetMeshFactory::buildTetsOnHex(const Teuchos::Tuple<int,3> & meshDesc,
                                        const Teuchos::Tuple<int,3> & element,
                                        stk::mesh::Part * block,
                                        const std::vector<stk::mesh::EntityId> & h_nodes, 
                                        STK_Interface & mesh) const
{
   Teuchos::FancyOStream out(Teuchos::rcpFromRef(std::cout));
   out.setShowProcRank(true);
   out.setOutputToRootOnly(-1);

   int totalXElems = meshDesc[0]; int totalYElems = meshDesc[1]; int totalZElems = meshDesc[2];
   int nx = element[0]; int ny = element[1]; int nz = element[2];

   stk::mesh::EntityId hex_id = totalXElems*totalYElems*nz+totalXElems*ny+nx+1;
   stk::mesh::EntityId gid_0 = 12*(hex_id-1)+1;
   std::vector<stk::mesh::EntityId> nodes(4);

   // add centroid node
   stk::mesh::EntityId centroid = 0;
   {
      stk::mesh::EntityId largestNode = (totalXElems+1)*(totalYElems+1)*(totalZElems+1);
      centroid = hex_id+largestNode;

      // compute average of coordinates
      std::vector<double> coord(3,0.0);
      for(std::size_t i=0;i<h_nodes.size();i++) {
         const double * node_coord = mesh.getNodeCoordinates(h_nodes[i]);
         coord[0] += node_coord[0];
         coord[1] += node_coord[1];
         coord[2] += node_coord[2];
      }
      coord[0] /= 8.0;
      coord[1] /= 8.0;
      coord[2] /= 8.0;
 
      mesh.addNode(centroid,coord);
   }

   // 
   int idSet[][3] = { { 0, 1, 2}, // back
                      { 0, 2, 3}, 
                      { 0, 5, 1}, // bottom
                      { 0, 4, 5},
                      { 0, 7, 4}, // left
                      { 0, 3, 7},
                      { 6, 1, 5}, // right
                      { 6, 2, 1},
                      { 6, 3, 2}, // top
                      { 6, 7, 3},
                      { 6, 4, 7}, // front
                      { 6, 5, 4} };

   for(int i=0;i<12;i++) {
      nodes[0] = h_nodes[idSet[i][0]];
      nodes[1] = h_nodes[idSet[i][1]];
      nodes[2] = h_nodes[idSet[i][2]];
      nodes[3] = centroid;

      // add element to mesh
      mesh.addElement(rcp(new ElementDescriptor(gid_0+i,nodes)),block);
   }
}
Beispiel #17
0
 /**
  * Do the nodes in this way form a closed ring?
  */
 bool is_closed() const {
     return nodes().is_closed();
 }
Beispiel #18
0
MemoryMapNode* MemoryMap::existsNode(const Instance& origInst,
                                     const InstanceList &candidates) const
{
    if (!origInst.type())
        return 0;

//    if (origInst.type()->type() & BaseType::trLexical)
//        debugerr(QString("The given instance '%0' has the lexical type '%1' (0x%2)!")
//                 .arg(origInst.fullName())
//                 .arg(origInst.typeName())
//                 .arg((uint)origInst.type()->id()));

    MemMapList nodes(findAllNodes(origInst, candidates));

    // Did we find any node?
    if (nodes.isEmpty())
        return 0;

    bool found = false, done = false;
    int i = 0;
    const MemoryMapNode *n = 0, *funcNode = 0;
    const BaseType* instType;
    quint64 instAddr;

    // Compare all given instances against all nodes found
    while (!found && !done) {
        // Try all candidates from the list first, finally the original instance
        if (i < candidates.size()) {
            instType = candidates[i].type();
            instAddr = candidates[i].address();
            ++i;
        }
        else {
            instType = origInst.type();
            instAddr = origInst.address();
            done = true;
        }

        // Compare the current instance with all nodes found
        for (MemMapList::const_iterator it = nodes.begin(), e = nodes.end();
             !found && it != e; ++it)
        {
            n = *it;
            // Does one node embed the instance?
            ObjectRelation orel = BaseType::embeds(n->type(), n->address(),
                                                   instType, instAddr);
            switch (orel) {
            // Conflict, ignored
            case orOverlap:
            case orCover:
                break;
            // Not found, continue
            case orNoOverlap:
                break;
            // We found the node
            case orEqual:
            case orFirstEmbedsSecond:
                found = true;
                break;
            // New instance embeds node, currently ignored
            case orSecondEmbedsFirst:
                break;
            }

            // Exit loop if node was found
            if (found)
                break;
            // Exit loop if object overlaps with a function
            if (n->type() && n->type()->type() == rtFunction)
                funcNode = n;
        }
    }

    if (found)
        return const_cast<MemoryMapNode*>(n);
    else if (funcNode)
        return const_cast<MemoryMapNode*>(funcNode);
//    else if (!nodes.isEmpty())
//        return const_cast<MemoryMapNode*>(nodes.first());
    else
        return 0;
//    return found ? const_cast<MemoryMapNode*>(n) : 0;
}
Beispiel #19
0
unsigned long update(MMSP::grid<dim, sparse<float> >& grid, int steps, int nthreads)
{

#if (!defined MPI_VERSION) && ((defined CCNI) || (defined BGQ))
    std::cerr<<"Error: MPI is required for CCNI."<<std::endl;
    exit(1);
#endif
    int rank=0;
    unsigned int np=0;
#ifdef MPI_VERSION
    rank=MPI::COMM_WORLD.Get_rank();
    np=MPI::COMM_WORLD.Get_size();
#endif

#ifndef SILENT
    static int iterations = 1;
    if (rank==0) print_progress(0, steps, iterations);
#endif

    unsigned long timer = 0;
    for (int step = 0; step < steps; step++) {
        unsigned long comptime=rdtsc();
        // update grid must be overwritten each time
        MMSP::grid<dim, sparse<float> > update(grid);
        ghostswap(grid);

        pthread_t * p_threads = new pthread_t[ nthreads];
        update_thread_para<dim>* update_para = new update_thread_para<dim>[nthreads];
        pthread_attr_t attr;
        pthread_attr_init (&attr);
        unsigned long nincr = nodes(grid)/nthreads;
        unsigned long ns = 0;

        for(int i=0; i<nthreads; i++) {
            update_para[i].nstart=ns;
            ns+=nincr;
            update_para[i].nend=ns;

            update_para[i].grid= &grid;
            update_para[i].update= &update;

            pthread_create(&p_threads[i], &attr, update_threads_helper<dim>, (void *) &update_para[i] );
        }

        for(int i=0; i!= nthreads ; i++) {
            pthread_join(p_threads[i], NULL);
        }

        delete [] p_threads ;
        delete [] update_para ;

#ifndef SILENT
        if (rank==0) print_progress(step+1, steps, iterations);
#endif
        swap(grid, update);
        timer += rdtsc() - comptime;
    } // Loop over steps
    ghostswap(grid);
#ifndef SILENT
    ++iterations;
#endif

    unsigned long total_update_time=timer;
#ifdef MPI_VERSION
    MPI::COMM_WORLD.Allreduce(&timer, &total_update_time, 1, MPI_UNSIGNED_LONG, MPI_SUM);
#endif
    return total_update_time/np; // average update time
}
Beispiel #20
0
void oneRun(char * args)
{
    Input input;
    Matrix<double> cuad(41, 2);
    Model *model = new Model();
    ModelFactory *modelFactory;
    PatternMatrix *dataSet;
    Matrix<double> *theta;
    Matrix<double> *weight;
    
    modelFactory = new SICSGeneralModel();
    dataSet = new PatternMatrix(0);
    theta = new Matrix<double>(1, 41);
    weight = new Matrix<double>(1, 41);

    input.importCSV((char *) "Cuads.csv", cuad, 1, 0);
    input.importCSV(args, *dataSet, 1, 0);
    
    model->setModel(modelFactory, ESTIMATION_MODEL);
    delete modelFactory;
    
    model->getItemModel()->setDataset(dataSet);

    for (int k = 0; k < cuad.nR(); k++)
    {
		(*theta)(0, k) = cuad(k, 0);
		(*weight)(0, k) = cuad(k, 1);
	}

	// build parameter set
	model->getParameterModel()->buildParameterSet(model->getItemModel(), model->getDimensionModel());

	// Create estimation
	EMEstimation em;
	//Here is where quadratures must be set.
	//create the quad nodes
	QuadratureNodes nodes(theta, weight);
	em.setQuadratureNodes(&nodes);
	em.setModel(model);
	em.setInitialValues(Constant::ANDRADE);
	//Pass the profiler to the estimation object so it can be used to profile each step
	//Run the estimation
	em.estimate();

	/*
	 * Now we will run the estimation of individual parameter
	 */
	//first create the latenTrait objects
	//LatentTraits * latentTraits;
	//latentTraits = new LatentTraits(dataSet);
	//Now create the estimation
	//LatentTraitEstimation * lte = new LatentTraitEstimation();
	//Pass the model
	//lte->setModel(model);
	//Pass the latent traits
	//lte->setLatentTraits(latentTraits);
	//Pass the quadrature nodes
	//lte->setQuadratureNodes(&nodes);
	//Ready to estimate
	//lte->estimateLatentTraitsEAP();
	//lte->estimateLatentTraitsMAP();
	//finished
	//now read the latent traits but we will do this later
	//lte->getLatentTraits()->print();

	//Matrix<double> data(dataSet->countIndividuals(), dataSet->countItems());
	//input.importCSV(args, data, 1, 0);
	
	//double* itemsf = new double[ data.nC()];
	//itemFit(latentTraits->pm, *(latentTraits->traits), data, model->getParameterModel()->getParameterSet(), model -> type,itemsf);
	//personFit(latentTraits->pm, *(latentTraits->traits), data, model->getParameterModel()->getParameterSet(), model -> type);

	delete dataSet;
	delete model;
	delete theta;
	delete weight;
}
Beispiel #21
0
// -----------------------------------------------------------------------------
PyObject* graph_create_minimum_spanning_tree_unique_distances(GraphObject* so, 
      PyObject* images, PyObject* uniq_dists) {

   PyObject* images_seq = PySequence_Fast(images, "images must be iteratable");
   if (images_seq == NULL)
      return NULL;

   static PyTypeObject* imagebase = 0;
   if (imagebase == 0) {
      PyObject* mod = PyImport_ImportModule(CHAR_PTR_CAST "gamera.gameracore");
      if (mod == 0) {
         PyErr_SetString(PyExc_RuntimeError, "Unable to load gameracore.\n");
         Py_DECREF(images_seq);
         return 0;
      }
      PyObject* dict = PyModule_GetDict(mod);
      if (dict == 0) {
         PyErr_SetString(PyExc_RuntimeError, "Unable to get module dictionary\n");
         Py_DECREF(images_seq);
         return 0;
      }
      imagebase = (PyTypeObject*)PyDict_GetItemString(dict, "Image");
   }

   // get the matrix
   if (!PyObject_TypeCheck(uniq_dists, imagebase)
         || get_pixel_type(uniq_dists) != Gamera::FLOAT) {
      PyErr_SetString(PyExc_TypeError, "uniq_dists must be a float image.");
      Py_DECREF(images_seq);
      return 0;
   }
   FloatImageView* dists = (FloatImageView*)((RectObject*)uniq_dists)->m_x;
   if (dists->nrows() != dists->ncols()) {
      PyErr_SetString(PyExc_TypeError, "image must be symmetric.");
      Py_DECREF(images_seq);
      return 0;
   }

   // get the graph ready
   so->_graph->remove_all_edges();
   GRAPH_UNSET_FLAG(so->_graph, FLAG_CYCLIC);

   // make the list for sorting
   typedef std::vector<std::pair<size_t, size_t> > index_vec_type;
   index_vec_type indexes(((dists->nrows() * dists->nrows()) - dists->nrows()) / 2);
   size_t row, col, index = 0;
   for (row = 0; row < dists->nrows(); ++row) {
      for (col = row + 1; col < dists->nrows(); ++col) {
         indexes[index].first = row;
         indexes[index++].second = col;
      }
   }
   std::sort(indexes.begin(), indexes.end(), DistsSorter(dists));

   // Add the nodes to the graph and build our map for later
   int images_len = PySequence_Fast_GET_SIZE(images_seq);
   std::vector<Node*> nodes(images_len);
   int i;
   for (i = 0; i < images_len; ++i) {
      GraphDataPyObject* obj = new GraphDataPyObject(PySequence_Fast_GET_ITEM(images_seq, i));
      nodes[i] = so->_graph->add_node_ptr(obj);
      assert(nodes[i] != NULL);
   }
   Py_DECREF(images_seq);

   // create the mst using kruskal
   i = 0;
   while (i < int(indexes.size()) && (int(so->_graph->get_nedges()) 
            < (images_len - 1))) {

      size_t row = indexes[i].first;
      size_t col = indexes[i].second;
      cost_t weight = dists->get(Point(col, row));
      so->_graph->add_edge(nodes[row], nodes[col], weight);
      ++i;
   }

   RETURN_VOID();
}
Beispiel #22
0
void Elem::refine (MeshRefinement& mesh_refinement)
{
  libmesh_assert (this->refinement_flag() == Elem::REFINE);
  libmesh_assert (this->active());

  // Create my children if necessary
  if (!_children)
    {
      _children = new Elem*[this->n_children()];

      unsigned int parent_p_level = this->p_level();
      for (unsigned int c=0; c<this->n_children(); c++)
        {
	  _children[c] = Elem::build(this->type(), this).release();
	  _children[c]->set_refinement_flag(Elem::JUST_REFINED);
	  _children[c]->set_p_level(parent_p_level);
	  _children[c]->set_p_refinement_flag(this->p_refinement_flag());
        }

      // Compute new nodal locations
      // and asssign nodes to children
      // Make these static.  It is unlikely the
      // sizes will change from call to call, so having these
      // static should save on reallocations
      std::vector<std::vector<Point> >        p    (this->n_children());
      std::vector<std::vector<Node*> >        nodes(this->n_children());


      // compute new nodal locations
      for (unsigned int c=0; c<this->n_children(); c++)
        {
          Elem *child = this->child(c);
	  p[c].resize    (child->n_nodes());
	  nodes[c].resize(child->n_nodes());

	  for (unsigned int nc=0; nc<child->n_nodes(); nc++)
	    {
	      // zero entries
	      p[c][nc].zero();
	      nodes[c][nc] = NULL;

	      for (unsigned int n=0; n<this->n_nodes(); n++)
	        {
		  // The value from the embedding matrix
		  const float em_val = this->embedding_matrix(c,nc,n);

		  if (em_val != 0.)
		    {
		      p[c][nc].add_scaled (this->point(n), em_val);

		      // We may have found the node, in which case we
		      // won't need to look it up later.
		      if (em_val == 1.)
		        nodes[c][nc] = this->get_node(n);
		    }
	        }
	    }

	// assign nodes to children & add them to the mesh
          const Real pointtol = this->hmin() * TOLERANCE;
	  for (unsigned int nc=0; nc<child->n_nodes(); nc++)
	    {
	      if (nodes[c][nc] != NULL)
	        {
		  child->set_node(nc) = nodes[c][nc];
	        }
	      else
	        {
		  child->set_node(nc) =
		    mesh_refinement.add_point(p[c][nc],
					      child->processor_id(),
                                              pointtol);
		  child->get_node(nc)->set_n_systems
                    (this->n_systems());
	        }
	    }

	  mesh_refinement.add_elem (child);
          child->set_n_systems(this->n_systems());
        }
    }
  else
    {
      unsigned int parent_p_level = this->p_level();
      for (unsigned int c=0; c<this->n_children(); c++)
        {
          Elem *child = this->child(c);
          libmesh_assert(child->subactive());
          child->set_refinement_flag(Elem::JUST_REFINED);
          child->set_p_level(parent_p_level);
          child->set_p_refinement_flag(this->p_refinement_flag());
        }
    }

  // Un-set my refinement flag now
  this->set_refinement_flag(Elem::INACTIVE);
  this->set_p_refinement_flag(Elem::INACTIVE);

  for (unsigned int c=0; c<this->n_children(); c++)
    {
      libmesh_assert(this->child(c)->parent() == this);
      libmesh_assert(this->child(c)->active());
    }
  libmesh_assert (this->ancestor());
}
Beispiel #23
0
void
AnnularMesh::buildMesh()
{
  const Real dt = (_tmax - _tmin) / _nt;

  MeshBase & mesh = getMesh();
  mesh.clear();
  mesh.set_mesh_dimension(2);
  mesh.set_spatial_dimension(2);
  BoundaryInfo & boundary_info = mesh.get_boundary_info();

  const unsigned num_angular_nodes = (_full_annulus ? _nt : _nt + 1);
  const unsigned num_nodes =
      (_rmin > 0.0 ? (_nr + 1) * num_angular_nodes : _nr * num_angular_nodes + 1);
  const unsigned min_nonzero_layer_num = (_rmin > 0.0 ? 0 : 1);
  std::vector<Node *> nodes(num_nodes);
  unsigned node_id = 0;

  // add nodes at rmax that aren't yet connected to any elements
  Real current_r = _rmax;
  for (unsigned angle_num = 0; angle_num < num_angular_nodes; ++angle_num)
  {
    const Real angle = _tmin + angle_num * dt;
    const Real x = current_r * std::cos(angle);
    const Real y = current_r * std::sin(angle);
    nodes[node_id] = mesh.add_point(Point(x, y, 0.0), node_id);
    node_id++;
  }

  // add nodes at smaller radii, and connect them with elements
  for (unsigned layer_num = _nr; layer_num > min_nonzero_layer_num; --layer_num)
  {
    if (layer_num == 1)
      current_r = _rmin; // account for precision loss
    else
      current_r -= _len * std::pow(_growth_r, layer_num - 1);

    // add node at angle = _tmin
    nodes[node_id] = mesh.add_point(
        Point(current_r * std::cos(_tmin), current_r * std::sin(_tmin), 0.0), node_id);
    node_id++;
    for (unsigned angle_num = 1; angle_num < num_angular_nodes; ++angle_num)
    {
      const Real angle = _tmin + angle_num * dt;
      const Real x = current_r * std::cos(angle);
      const Real y = current_r * std::sin(angle);
      nodes[node_id] = mesh.add_point(Point(x, y, 0.0), node_id);
      Elem * elem = mesh.add_elem(new Quad4);
      elem->set_node(0) = nodes[node_id];
      elem->set_node(1) = nodes[node_id - 1];
      elem->set_node(2) = nodes[node_id - num_angular_nodes - 1];
      elem->set_node(3) = nodes[node_id - num_angular_nodes];
      elem->subdomain_id() = _quad_subdomain_id;
      node_id++;

      if (layer_num == _nr)
        // add outer boundary (boundary_id = 1)
        boundary_info.add_side(elem, 2, 1);
      if (layer_num == 1)
        // add inner boundary (boundary_id = 0)
        boundary_info.add_side(elem, 0, 0);
      if (!_full_annulus && angle_num == 1)
        // add tmin boundary (boundary_id = 2)
        boundary_info.add_side(elem, 1, 2);
      if (!_full_annulus && angle_num == num_angular_nodes - 1)
        // add tmin boundary (boundary_id = 3)
        boundary_info.add_side(elem, 3, 3);
    }
    if (_full_annulus)
    {
      // add element connecting to node at angle=0
      Elem * elem = mesh.add_elem(new Quad4);
      elem->set_node(0) = nodes[node_id - num_angular_nodes];
      elem->set_node(1) = nodes[node_id - 1];
      elem->set_node(2) = nodes[node_id - num_angular_nodes - 1];
      elem->set_node(3) = nodes[node_id - 2 * num_angular_nodes];
      elem->subdomain_id() = _quad_subdomain_id;

      if (layer_num == _nr)
        // add outer boundary (boundary_id = 1)
        boundary_info.add_side(elem, 2, 1);
      if (layer_num == 1)
        // add inner boundary (boundary_id = 0)
        boundary_info.add_side(elem, 0, 0);
    }
  }

  // add single node at origin, if relevant
  if (_rmin == 0.0)
  {
    nodes[node_id] = mesh.add_point(Point(0.0, 0.0, 0.0), node_id);
    boundary_info.add_node(node_id, 0); // boundary_id=0 is centre
    for (unsigned angle_num = 0; angle_num < num_angular_nodes - 1; ++angle_num)
    {
      Elem * elem = mesh.add_elem(new Tri3);
      elem->set_node(0) = nodes[node_id];
      elem->set_node(1) = nodes[node_id - num_angular_nodes + angle_num];
      elem->set_node(2) = nodes[node_id - num_angular_nodes + angle_num + 1];
      elem->subdomain_id() = _tri_subdomain_id;
    }
    if (_full_annulus)
    {
      Elem * elem = mesh.add_elem(new Tri3);
      elem->set_node(0) = nodes[node_id];
      elem->set_node(1) = nodes[node_id - 1];
      elem->set_node(2) = nodes[node_id - num_angular_nodes];
      elem->subdomain_id() = _tri_subdomain_id;
    }
  }

  boundary_info.sideset_name(0) = "rmin";
  boundary_info.sideset_name(1) = "rmax";
  boundary_info.nodeset_name(0) = "rmin";
  boundary_info.nodeset_name(1) = "rmax";
  if (!_full_annulus)
  {
    boundary_info.sideset_name(2) = "tmin";
    boundary_info.sideset_name(3) = "tmax";
    boundary_info.nodeset_name(2) = "tmin";
    boundary_info.nodeset_name(3) = "tmax";
  }

  mesh.prepare_for_use(false);
}
Beispiel #24
0
  //
  // FindLoops
  //
  // Find loops and build loop forest using Havlak's algorithm, which
  // is derived from Tarjan. Variable names and step numbering has
  // been chosen to be identical to the nomenclature in Havlak's
  // paper (which is similar to the one used by Tarjan).
  //
  void FindLoops() {
    if (!CFG_->GetStartBasicBlock()) return;

    int                size = CFG_->GetNumNodes();

    IntSetVector       non_back_preds(size);
    IntListVector      back_preds(size);
    IntVector          header(size);
    CharVector         type(size);
    IntVector          last(size);
    NodeVector         nodes(size);
    BasicBlockMap      number;

    // Step a:
    //   - initialize all nodes as unvisited.
    //   - depth-first traversal and numbering.
    //   - unreached BB's are marked as dead.
    //
    for (MaoCFG::NodeMap::iterator bb_iter =
           CFG_->GetBasicBlocks()->begin();
         bb_iter != CFG_->GetBasicBlocks()->end(); ++bb_iter) {
      number[(*bb_iter).second] = kUnvisited;
    }

    DFS(CFG_->GetStartBasicBlock(), &nodes, &number, &last, 0);

    // Step b:
    //   - iterate over all nodes.
    //
    //   A backedge comes from a descendant in the DFS tree, and non-backedges
    //   from non-descendants (following Tarjan).
    //
    //   - check incoming edges 'v' and add them to either
    //     - the list of backedges (back_preds) or
    //     - the list of non-backedges (non_back_preds)
    //
    for (int w = 0; w < size; w++) {
      header[w] = 0;
      type[w] = BB_NONHEADER;

      BasicBlock *node_w = nodes[w].bb();
      if (!node_w) {
        type[w] = BB_DEAD;
        continue;  // dead BB
      }

      if (node_w->GetNumPred()) {
        for (BasicBlockIter inedges = node_w->in_edges()->begin();
             inedges != node_w->in_edges()->end(); ++inedges) {
          BasicBlock     *node_v = *inedges;

          int v = number[ node_v ];
          if (v == kUnvisited) continue;  // dead node

          if (IsAncestor(w, v, &last))
            back_preds[w].push_back(v);
          else
            non_back_preds[w].insert(v);
        }
      }
    }

    // Start node is root of all other loops.
    header[0] = 0;

    // Step c:
    //
    // The outer loop, unchanged from Tarjan. It does nothing except
    // for those nodes which are the destinations of backedges.
    // For a header node w, we chase backward from the sources of the
    // backedges adding nodes to the set P, representing the body of
    // the loop headed by w.
    //
    // By running through the nodes in reverse of the DFST preorder,
    // we ensure that inner loop headers will be processed before the
    // headers for surrounding loops.
    //
    for (int w = size-1; w >= 0; w--) {
      NodeList    node_pool;  // this is 'P' in Havlak's paper
      BasicBlock *node_w = nodes[w].bb();
      if (!node_w) continue;  // dead BB

      // Step d:
      IntList::iterator back_pred_iter  = back_preds[w].begin();
      IntList::iterator back_pred_end   = back_preds[w].end();
      for (; back_pred_iter != back_pred_end; back_pred_iter++) {
        int v = *back_pred_iter;
        if (v != w)
          node_pool.push_back(nodes[v].FindSet());
        else
          type[w] = BB_SELF;
      }

      // Copy node_pool to worklist.
      //
      NodeList worklist;
      NodeList::iterator niter  = node_pool.begin();
      NodeList::iterator nend   = node_pool.end();
      for (;  niter != nend; ++niter)
        worklist.push_back(*niter);

      if (!node_pool.empty())
        type[w] = BB_REDUCIBLE;

      // work the list...
      //
      while (!worklist.empty()) {
        UnionFindNode x = *worklist.front();
        worklist.pop_front();

        // Step e:
        //
        // Step e represents the main difference from Tarjan's method.
        // Chasing upwards from the sources of a node w's backedges. If
        // there is a node y' that is not a descendant of w, w is marked
        // the header of an irreducible loop, there is another entry
        // into this loop that avoids w.
        //

        // The algorithm has degenerated. Break and
        // return in this case.
        //
        size_t non_back_size = non_back_preds[x.dfs_number()].size();
        if (non_back_size > kMaxNonBackPreds) {
          lsg_->KillAll();
          return;
        }

        IntSet::iterator non_back_pred_iter =
          non_back_preds[x.dfs_number()].begin();
        IntSet::iterator non_back_pred_end  =
          non_back_preds[x.dfs_number()].end();
        for (; non_back_pred_iter != non_back_pred_end; non_back_pred_iter++) {
          UnionFindNode  y     = nodes[*non_back_pred_iter];
          UnionFindNode *ydash = y.FindSet();

          if (!IsAncestor(w, ydash->dfs_number(), &last)) {
            type[w] = BB_IRREDUCIBLE;
            non_back_preds[w].insert(ydash->dfs_number());
          } else {
            if (ydash->dfs_number() != w) {
              NodeList::iterator nfind = find(node_pool.begin(),
                                              node_pool.end(), ydash);
              if (nfind == node_pool.end()) {
                worklist.push_back(ydash);
                node_pool.push_back(ydash);
              }
            }
          }
        }
      }

      // Collapse/Unionize nodes in a SCC to a single node
      // For every SCC found, create a loop descriptor and link it in.
      //
      if (!node_pool.empty() || (type[w] == BB_SELF)) {
        SimpleLoop* loop = lsg_->CreateNewLoop();

        // At this point, one can set attributes to the loop, such as:
        //
        // the bottom node:
        //    IntList::iterator iter  = back_preds[w].begin();
        //    loop bottom is: nodes[*backp_iter].node);
        //
        // the number of backedges:
        //    back_preds[w].size()
        //
        // whether this loop is reducible:
        //    type[w] != BB_IRREDUCIBLE
        //
        // TODO(rhundt): Define those interfaces in the Loop Forest.
        //
        nodes[w].set_loop(loop);

        for (niter = node_pool.begin(); niter != node_pool.end(); niter++) {
          UnionFindNode  *node = (*niter);

          // Add nodes to loop descriptor.
          header[node->dfs_number()] = w;
          node->Union(&nodes[w]);

          // Nested loops are not added, but linked together.
          if (node->loop())
            node->loop()->set_parent(loop);
          else
            loop->AddNode(node->bb());
        }

        lsg_->AddLoop(loop);
      }  // node_pool.size
    }  // Step c
  }  // FindLoops
Beispiel #25
0
void generate(int dim, const char* filename)
{
	if (dim==1) {
		MMSP::grid<1,int> grid(0,0,128);

		for (int i=0; i<nodes(grid); i++) {
			vector<int> x = position(grid,i);
			double d = 64.0-x[0];
			if (d<32.0) grid(i) = 2;
			else grid(i) = 1;
		}

		for (int j=0; j<50; j++) {
			int i = rand()%nodes(grid);
			vector<int> p = position(grid,i);
			for (int x=p[0]-1; x<=p[0]+1; x++)
				grid[x] = 0;
		}

		output(grid,filename);
	}

	if (dim==2) {
		MMSP::grid<2,int> grid(0,0,128,0,128);

		for (int i=0; i<nodes(grid); i++) {
			vector<int> x = position(grid,i);
			double d = sqrt(pow(64.0-x[0],2)+pow(64.0-x[1],2));
			if (d<32.0) grid(i) = 2;
			else grid(i) = 1;
		}

		for (int j=0; j<50; j++) {
			int i = rand()%nodes(grid);
			vector<int> p = position(grid,i);
			for (int x=p[0]-1; x<=p[0]+1; x++)
				for (int y=p[1]-1; y<=p[1]+1; y++)
					grid[x][y] = 0;
		}

		output(grid,filename);
	}

	if (dim==3) {
		MMSP::grid<3,int> grid(0,0,64,0,64,0,64);

		for (int i=0; i<nodes(grid); i++) {
			vector<int> x = position(grid,i);
			double d = sqrt(pow(32.0-x[0],2)+pow(32.0-x[1],2)+pow(32.0-x[2],2));
			if (d<16.0) grid(i) = 2;
			else grid(i) = 1;
		}

		for (int j=0; j<50; j++) {
			int i = rand()%nodes(grid);
			vector<int> p = position(grid,i);
			for (int x=p[0]-1; x<=p[0]+1; x++)
				for (int y=p[1]-1; y<=p[1]+1; y++)
					for (int z=p[2]-1; z<=p[2]+1; z++)
						grid[x][y][z] = 0;
		}

		output(grid,filename);
	}
}
//---------------------------------------------------------------------------//
// Hex-8 test.
TEUCHOS_UNIT_TEST( MoabEntity, hex_8_test )
{
    // Extract the raw mpi communicator.
    Teuchos::RCP<const Teuchos::Comm<int> > comm = getDefaultComm<int>();
    Teuchos::RCP<const Teuchos::MpiComm<int> > mpi_comm = 
	Teuchos::rcp_dynamic_cast< const Teuchos::MpiComm<int> >( comm );
    Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > opaque_comm = 
	mpi_comm->getRawMpiComm();
    MPI_Comm raw_comm = (*opaque_comm)();

    // Create the mesh.
    int space_dim = 3;
    Teuchos::RCP<moab::Interface> moab_mesh = Teuchos::rcp( new moab::Core() );
    Teuchos::RCP<moab::ParallelComm> parallel_mesh =
	Teuchos::rcp( new moab::ParallelComm(moab_mesh.getRawPtr(),raw_comm) );

    // Create the nodes.
    moab::ErrorCode error = moab::MB_SUCCESS;
    Teuchos::Array<moab::EntityHandle> nodes(8);
    double node_coords[3];
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = -2.0;
    error = moab_mesh->create_vertex( node_coords, nodes[0] );
    TEST_EQUALITY( error, moab::MB_SUCCESS );

    node_coords[0] = 2.0;
    node_coords[1] = 0.0;
    node_coords[2] = -2.0;
    error = moab_mesh->create_vertex( node_coords, nodes[1] );
    TEST_EQUALITY( error, moab::MB_SUCCESS );

    node_coords[0] = 2.0;
    node_coords[1] = 2.0;
    node_coords[2] = -2.0;
    error = moab_mesh->create_vertex( node_coords, nodes[2] );
    TEST_EQUALITY( error, moab::MB_SUCCESS );

    node_coords[0] = 0.0;
    node_coords[1] = 2.0;
    node_coords[2] = -2.0;
    error = moab_mesh->create_vertex( node_coords, nodes[3] );
    TEST_EQUALITY( error, moab::MB_SUCCESS );

    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;
    error = moab_mesh->create_vertex( node_coords, nodes[4] );
    TEST_EQUALITY( error, moab::MB_SUCCESS );

    node_coords[0] = 2.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;
    error = moab_mesh->create_vertex( node_coords, nodes[5] );
    TEST_EQUALITY( error, moab::MB_SUCCESS );

    node_coords[0] = 2.0;
    node_coords[1] = 2.0;
    node_coords[2] = 0.0;
    error = moab_mesh->create_vertex( node_coords, nodes[6] );
    TEST_EQUALITY( error, moab::MB_SUCCESS );

    node_coords[0] = 0.0;
    node_coords[1] = 2.0;
    node_coords[2] = 0.0;
    error = moab_mesh->create_vertex( node_coords, nodes[7] );
    TEST_EQUALITY( error, moab::MB_SUCCESS );

    // Make a hex-8.
    moab::EntityHandle hex_entity;
    error = moab_mesh->create_element( moab::MBHEX,
				       nodes.getRawPtr(),
				       8,
				       hex_entity );
    TEST_EQUALITY( error, moab::MB_SUCCESS );

    // Index the sets in the mesh.
    Teuchos::RCP<DataTransferKit::MoabMeshSetIndexer> set_indexer =
	Teuchos::rcp( new DataTransferKit::MoabMeshSetIndexer(parallel_mesh) );

    // Create a DTK entity for the hex.
    DataTransferKit::Entity dtk_entity = DataTransferKit::MoabEntity( 
	hex_entity, parallel_mesh.ptr(), set_indexer.ptr() );
    
    // Create a local map from the moab mesh.
    Teuchos::RCP<DataTransferKit::EntityLocalMap> local_map =
	Teuchos::rcp( new DataTransferKit::MoabEntityLocalMap(parallel_mesh) );

    // Test the measure.
    TEST_EQUALITY( local_map->measure(dtk_entity), 8.0 );

    // Test the centroid.
    Teuchos::Array<double> centroid( space_dim, 0.0 );
    local_map->centroid( dtk_entity, centroid() );
    TEST_EQUALITY( centroid[0], 1.0 );
    TEST_EQUALITY( centroid[1], 1.0 );
    TEST_EQUALITY( centroid[2], -1.0 );

    // Make a good point and a bad point.
    Teuchos::Array<double> good_point( space_dim );
    good_point[0] = 0.5;
    good_point[1] = 1.5;
    good_point[2] = -1.0;
    Teuchos::Array<double> bad_point( space_dim );
    bad_point[0] = 0.75;
    bad_point[1] = -1.75;
    bad_point[2] = 0.35;

    // Test the reference frame safeguard.
    TEST_ASSERT(
    	local_map->isSafeToMapToReferenceFrame(dtk_entity,good_point()) );
    TEST_ASSERT(
    	!local_map->isSafeToMapToReferenceFrame(dtk_entity,bad_point()) );

    // Test the mapping to reference frame.
    Teuchos::Array<double> ref_good_point( space_dim );
    bool good_map = local_map->mapToReferenceFrame( 
    	dtk_entity, good_point(), ref_good_point() );
    TEST_ASSERT( good_map );
    TEST_FLOATING_EQUALITY( ref_good_point[0], -0.5, epsilon );
    TEST_FLOATING_EQUALITY( ref_good_point[1], 0.5, epsilon );
    TEST_ASSERT( std::abs(ref_good_point[2]) < epsilon );
			    
    Teuchos::Array<double> ref_bad_point( space_dim );
    bool bad_map = local_map->mapToReferenceFrame( 
    	dtk_entity, bad_point(), ref_bad_point() );
    TEST_ASSERT( !bad_map );

    // Test the point inclusion.
    TEST_ASSERT( local_map->checkPointInclusion(dtk_entity,ref_good_point()) );
    TEST_ASSERT( !local_map->checkPointInclusion(dtk_entity,ref_bad_point()) );

    // Test the map to physical frame.
    Teuchos::Array<double> phy_good_point( space_dim );
    local_map->mapToPhysicalFrame(dtk_entity,ref_good_point(),phy_good_point());
    TEST_FLOATING_EQUALITY( good_point[0], phy_good_point[0], epsilon );
    TEST_FLOATING_EQUALITY( good_point[1], phy_good_point[1], epsilon );
    TEST_FLOATING_EQUALITY( good_point[2], phy_good_point[2], epsilon );

    Teuchos::Array<double> phy_bad_point( space_dim );
    local_map->mapToPhysicalFrame(dtk_entity,ref_bad_point(),phy_bad_point());
    TEST_FLOATING_EQUALITY( bad_point[0], phy_bad_point[0], epsilon );
    TEST_FLOATING_EQUALITY( bad_point[1], phy_bad_point[1], epsilon );
    TEST_FLOATING_EQUALITY( bad_point[2], phy_bad_point[2], epsilon );

    // Test the coordinates of the points extracted through the centroid
    // function.
    DataTransferKit::Entity dtk_node;
    Teuchos::Array<double> point_coords(space_dim);
    int num_nodes = 8;
    for ( int n = 0; n < num_nodes; ++n )
    {
	dtk_node = DataTransferKit::MoabEntity( 
	    nodes[n], parallel_mesh.ptr(), set_indexer.ptr() );
	local_map->centroid( dtk_node, point_coords() );
	moab_mesh->get_coords( &nodes[n], 1, node_coords );
	TEST_EQUALITY( node_coords[0], point_coords[0] );
	TEST_EQUALITY( node_coords[1], point_coords[1] );
	TEST_EQUALITY( node_coords[2], point_coords[2] );
    }
}
void generate(int dim, char* filename)
{
	int rank=0;
	#ifdef MPI_VERSION
	rank = MPI::COMM_WORLD.Get_rank();
	#endif
	if (rank==0) {
		std::ofstream vfile("v.log",std::ofstream::out);
		vfile.close();
	}


	if (dim == 2)	{
		const int Lx = 768;
		const int Ly = 128;

		grid<2,sparse<phi_type> > initGrid(0, 0,Lx, 0,Ly);

		for (int d=0; d<dim; d++) {
			if (x0(initGrid, d) == g0(initGrid,d))
				b0(initGrid,d) = Dirichlet;
			else if (x1(initGrid,d) == g1(initGrid,d))
				b1(initGrid,d) = Dirichlet;
		}

		for (int n=0; n<nodes(initGrid); n++) {
			vector<int> x = position(initGrid, n);
			if (x[0]>Ly && x[1]>0.25*Ly && x[1]<0.75*Ly)
				set(initGrid(n), 0) = 1.0;
			else if (x[1]<Ly/2)
				set(initGrid(n), 1) = 1.0;
			else
				set(initGrid(n), 2) = 1.0;
		}

		output(initGrid, filename);
	}

	if (dim == 3)	{
		const int Lx = 512;
		const int Ly = 256;
		const int Lz = 64;

		grid<3,sparse<phi_type> > initGrid(0, 0,Lx, 0,Ly, 0,Lz);

		for (int d=0; d<dim; d++) {
			if (x0(initGrid, d) == g0(initGrid,d))
				b0(initGrid,d) = Dirichlet;
			else if (x1(initGrid,d) == g1(initGrid,d))
				b1(initGrid,d) = Dirichlet;
		}

		for (int n=0; n<nodes(initGrid); n++) {
			vector<int> x = position(initGrid, n);
			if (x[0]>Ly && x[1]>0.25*Ly && x[1]<0.75*Ly)
				set(initGrid(n), 0) = 1.0;
			else if (x[1]<Ly/2)
				set(initGrid(n), 1) = 1.0;
			else
				set(initGrid(n), 2) = 1.0;
		}

		output(initGrid, filename);
	}
}
Beispiel #28
0
 bool ends_have_same_id() const {
     return nodes().ends_have_same_id();
 }
//---------------------------------------------------------------------------//
// Hex-8 test.
TEUCHOS_UNIT_TEST( STKMeshEntityIntegrationRule, hex_8_test )
{
    // Extract the raw mpi communicator.
    Teuchos::RCP<const Teuchos::Comm<int> > comm = 
	Teuchos::DefaultComm<int>::getComm();
    Teuchos::RCP<const Teuchos::MpiComm<int> > mpi_comm = 
	Teuchos::rcp_dynamic_cast< const Teuchos::MpiComm<int> >( comm );
    Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > opaque_comm = 
	mpi_comm->getRawMpiComm();
    MPI_Comm raw_comm = (*opaque_comm)();

    // Create meta data.
    int space_dim = 3;
    stk::mesh::MetaData meta_data( space_dim );

    // Make two parts.
    std::string p1_name = "part_1";
    stk::mesh::Part& part_1 = meta_data.declare_part( p1_name );
    stk::mesh::set_topology( part_1, stk::topology::HEX_8 );

    // Make a data field.
    stk::mesh::Field<double, stk::mesh::Cartesian3d>& data_field =
	meta_data.declare_field<
	stk::mesh::Field<double, stk::mesh::Cartesian3d> >(
	    stk::topology::NODE_RANK, "test field");
    meta_data.set_coordinate_field( &data_field );
    stk::mesh::put_field( data_field, part_1 );
    meta_data.commit();

    // Create bulk data.
    Teuchos::RCP<stk::mesh::BulkData> bulk_data =
	Teuchos::rcp( new stk::mesh::BulkData(meta_data,raw_comm) );
    bulk_data->modification_begin();

    // Make a hex-8.
    int comm_rank = comm->getRank();
    stk::mesh::EntityId hex_id = 23 + comm_rank;
    stk::mesh::Entity hex_entity = 
	bulk_data->declare_entity( stk::topology::ELEM_RANK, hex_id, part_1 );
    unsigned num_nodes = 8;
    Teuchos::Array<stk::mesh::EntityId> node_ids( num_nodes );
    Teuchos::Array<stk::mesh::Entity> nodes( num_nodes );
    for ( unsigned i = 0; i < num_nodes; ++i )
    {
	node_ids[i] = num_nodes*comm_rank + i + 5;
	nodes[i] = bulk_data->declare_entity( 
	    stk::topology::NODE_RANK, node_ids[i], part_1 );
	bulk_data->declare_relation( hex_entity, nodes[i], i );
    }
    bulk_data->modification_end();

    // Create a DTK entity for the hex.
    DataTransferKit::Entity dtk_entity = 
	DataTransferKit::STKMeshEntity( hex_entity, bulk_data.ptr() );

    // Create an integration rule.
    Teuchos::RCP<DataTransferKit::EntityIntegrationRule> integration_rule =
	Teuchos::rcp( new DataTransferKit::STKMeshEntityIntegrationRule(bulk_data) );

    // Test the integration rule.
    Teuchos::Array<Teuchos::Array<double> > p_1;
    Teuchos::Array<double> w_1;
    integration_rule->getIntegrationRule( dtk_entity, 1, p_1, w_1 );
    TEST_EQUALITY( 1, w_1.size() );
    TEST_EQUALITY( 1, p_1.size() );
    TEST_EQUALITY( 3, p_1[0].size() );
    TEST_EQUALITY( 8.0, w_1[0] );
    TEST_EQUALITY( 0.0, p_1[0][0] );
    TEST_EQUALITY( 0.0, p_1[0][1] );
    TEST_EQUALITY( 0.0, p_1[0][2] );

    Teuchos::Array<Teuchos::Array<double> > p_2;
    Teuchos::Array<double> w_2;
    integration_rule->getIntegrationRule( dtk_entity, 2, p_2, w_2 );
    TEST_EQUALITY( 8, w_2.size() );
    TEST_EQUALITY( 8, p_2.size() );
    for ( int i = 0; i < 8; ++i )
    {
	TEST_EQUALITY( w_2[i], 1.0 );
	TEST_EQUALITY( p_2[i].size(), 3 );

	for ( int d = 0; d < 3; ++d )
	{
	    TEST_FLOATING_EQUALITY(
		std::abs(p_2[i][d]), 1.0 / std::sqrt(3.0), 1.0e-15 );
	}
    }
}
Beispiel #30
0
		inline ::libmaus2::util::shared_ptr < libmaus2::huffman::HuffmanTreeNode >::type libmaus2::huffman::HuffmanTreeNode::simpleDeserialise(::std::istream & in)
		{
			::std::string line;
			::std::getline(in,line);

			::std::deque< ::std::string> tokens = ::libmaus2::util::stringFunctions::tokenize< ::std::string>(line,"\t");

			if ( tokens.size() != 2 || (tokens[0] != "HuffmanTreeNode") )
				throw ::std::runtime_error("Malformed input in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");

			uint64_t const numnodes = atol( tokens[1].c_str() );
			::std::vector < ::libmaus2::huffman::HuffmanTreeNode * > nodes(numnodes);

			try
			{
				::libmaus2::util::shared_ptr < ::libmaus2::huffman::HuffmanTreeNode >::type sroot;

				for ( uint64_t i = 0; i < numnodes; ++i )
				{
					::std::getline(in,line);

					if ( ! in )
						throw ::std::runtime_error("Stream invalid before read complete in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");

					tokens = ::libmaus2::util::stringFunctions::tokenize< ::std::string>(line,"\t");

					if ( tokens.size() < 2 )
						throw ::std::runtime_error("Invalid input in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");

					if ( tokens[1] == "inner" )
					{
						if ( tokens.size() != 4 )
							throw ::std::runtime_error("Invalid input in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");

						uint64_t const nodeid = atol( tokens[0].c_str() );

						if ( nodeid >= numnodes )
							throw ::std::runtime_error("Invalid node id in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");

						if ( nodes[nodeid] )
							throw ::std::runtime_error("Repeated node in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");

						uint64_t const left = atol(tokens[2].c_str());
						uint64_t const right = atol(tokens[3].c_str());

						if ( left >= numnodes || (!nodes[left]) )
							throw ::std::runtime_error("Invalid node id in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");
						if ( right >= numnodes || (!nodes[right]) )
							throw ::std::runtime_error("Invalid node id in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");

						nodes [ nodeid ] = new  ::libmaus2::huffman::HuffmanTreeInnerNode(0,0,nodes[left]->getFrequency() + nodes[right]->getFrequency() );

						if ( left )
						{
							dynamic_cast < ::libmaus2::huffman::HuffmanTreeInnerNode * > (nodes [ nodeid ])->left = nodes[left]; nodes[left] = 0;
						}
						if ( right )
						{
							dynamic_cast < ::libmaus2::huffman::HuffmanTreeInnerNode * > (nodes [ nodeid ])->right = nodes[right]; nodes[right] = 0;
						}
					}
					else if ( tokens[1] == "leaf" )
					{
						if ( tokens.size() != 4 )
							throw ::std::runtime_error("Invalid input in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");

						uint64_t const nodeid = atol( tokens[0].c_str() );

						if ( nodeid >= numnodes )
							throw ::std::runtime_error("Invalid node id in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");

						int const symbol = atoi(tokens[2].c_str());
						uint64_t const frequency = atol(tokens[3].c_str());

						nodes[nodeid] = new  ::libmaus2::huffman::HuffmanTreeLeaf(symbol,frequency);
					}
					else
					{
						throw ::std::runtime_error("Invalid node type in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");
					}
				}

				if ( ! nodes[0] )
					throw ::std::runtime_error("No root node produced in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");

				for ( uint64_t i = 1; i < numnodes; ++i )
					if ( nodes[i] )
						throw ::std::runtime_error("Unlinked node produced in ::libmaus2::huffman::HuffmanTreeNode::simpleDeserialise()");

				sroot = ::libmaus2::util::shared_ptr< ::libmaus2::huffman::HuffmanTreeNode>::type(nodes[0]);
				nodes[0] = 0;

				return sroot;
			}
			catch(...)
			{
				for ( uint64_t i = 0; i < nodes.size(); ++i )
					delete  nodes[i];
				throw;
			}
		}