Exemplo n.º 1
0
int main(int argc, char* argv[])
{
	if (MPI_Init(&argc, &argv) != MPI_SUCCESS) {
		cerr << "Coudln't initialize MPI." << endl;
		abort();
	}

	MPI_Comm comm = MPI_COMM_WORLD;

	int rank = 0, comm_size = 0;
	MPI_Comm_rank(comm, &rank);
	MPI_Comm_size(comm, &comm_size);

	float zoltan_version;
	if (Zoltan_Initialize(argc, argv, &zoltan_version) != ZOLTAN_OK) {
	    cout << "Zoltan_Initialize failed" << endl;
	    abort();
	}

	Dccrg<std::array<int, 2>> grid;

	const std::array<uint64_t, 3> grid_length = {{18, 18, 1}};
	grid
		.set_initial_length(grid_length)
		.set_neighborhood_length(2)
		.set_maximum_refinement_level(0)
		.set_periodic(true, true, true)
		.set_load_balancing_method("RANDOM")
		.initialize(comm);

	/*
	Use a neighborhood like this in the z plane:
	O.O.O
	.....
	O.X.O
	.....
	O.O.O
	and play 4 interlaced games simultaneously.
	*/
	typedef dccrg::Types<3>::neighborhood_item_t neigh_t;
	const std::vector<neigh_t> neighborhood{
		{-2, -2, 0},
		{-2,  0, 0},
		{-2,  2, 0},
		{ 0, -2, 0},
		{ 0,  2, 0},
		{ 2, -2, 0},
		{ 2,  0, 0},
		{ 2,  2, 0}
	};

	const int neighborhood_id = 1;
	if (!grid.add_neighborhood(neighborhood_id, neighborhood)) {
		std::cerr << __FILE__ << ":" << __LINE__
			<< " Couldn't set neighborhood"
			<< std::endl;
		abort();
	}

	// initial condition
	const std::unordered_set<uint64_t> live_cells = get_live_cells(grid_length[0], 0);
	for (const uint64_t cell: live_cells) {
		auto* const cell_data = grid[cell];
		if (cell_data != nullptr) {
			(*cell_data)[0] = 1;
		}
	}

	// every process outputs the game state into its own file
	ostringstream basename, suffix(".vtk");
	basename << "tests/user_neighborhood/general_neighborhood_" << rank << "_";
	ofstream outfile, visit_file;

	// visualize the game with visit -o game_of_life_test.visit
	if (rank == 0) {
		visit_file.open("tests/user_neighborhood/general_neighborhood.visit");
		visit_file << "!NBLOCKS " << comm_size << endl;
	}

	#define TIME_STEPS 36
	for (int step = 0; step < TIME_STEPS; step++) {

		grid.balance_load();
		grid.update_copies_of_remote_neighbors(neighborhood_id);

		// check that the result is correct
		if (step % 4 == 0) {
			const std::unordered_set<uint64_t> live_cells = get_live_cells(grid_length[0], step);
			for (const auto& cell: grid.local_cells(neighborhood_id)) {
				if ((*cell.data)[0] == 0) {
					if (live_cells.count(cell.id) > 0) {
						std::cerr << __FILE__ << ":" << __LINE__
							<< " Cell " << cell.id
							<< " shouldn't be alive on step " << step
							<< endl;
						abort();
					}
				} else {
					if (live_cells.count(cell.id) == 0) {
						std::cerr << __FILE__ << ":" << __LINE__
							<< " Cell " << cell.id
							<< " should be alive on step " << step
							<< endl;
						abort();
					}
				}
			}
		}

		// write the game state into a file named according to the current time step
		string current_output_name("");
		ostringstream step_string;
		step_string.fill('0');
		step_string.width(5);
		step_string << step;
		current_output_name += basename.str();
		current_output_name += step_string.str();
		current_output_name += suffix.str();

		// visualize the game with visit -o game_of_life_test.visit
		if (rank == 0) {
			for (int process = 0; process < comm_size; process++) {
				visit_file << "general_neighborhood_" << process << "_" << step_string.str() << suffix.str() << endl;
			}
		}

		// write the grid into a file
		vector<uint64_t> cells = grid.get_cells();
		sort(cells.begin(), cells.end());
		grid.write_vtk_file(current_output_name.c_str());
		// prepare to write the game data into the same file
		outfile.open(current_output_name.c_str(), ofstream::app);
		outfile << "CELL_DATA " << cells.size() << endl;

		// go through the grids cells and write their state into the file
		outfile << "SCALARS is_alive float 1" << endl;
		outfile << "LOOKUP_TABLE default" << endl;
		for (const uint64_t cell: cells) {
			const auto* const cell_data = grid[cell];

			if ((*cell_data)[0] == 1) {
				// color live cells of interlaced games differently
				const Types<3>::indices_t indices = grid.mapping.get_indices(cell);
				outfile << 1 + indices[0] % 2 + (indices[1] % 2) * 2;
			} else {
				outfile << 0;
			}
			outfile << endl;
		}

		// write each cells live neighbor count
		outfile << "SCALARS live_neighbor_count float 1" << endl;
		outfile << "LOOKUP_TABLE default" << endl;
		for (const uint64_t cell: cells) {
			const auto* const cell_data = grid[cell];
			outfile << (*cell_data)[1] << endl;
		}

		// write each cells neighbor count
		outfile << "SCALARS neighbors int 1" << endl;
		outfile << "LOOKUP_TABLE default" << endl;
		for (const uint64_t cell: cells) {
			const auto* const neighbors = grid.get_neighbors_of(cell);
			outfile << neighbors->size() << endl;
		}

		// write each cells process
		outfile << "SCALARS process int 1" << endl;
		outfile << "LOOKUP_TABLE default" << endl;
		for (size_t i = 0; i < cells.size(); i++) {
			outfile << rank << endl;
		}

		// write each cells id
		outfile << "SCALARS id int 1" << endl;
		outfile << "LOOKUP_TABLE default" << endl;
		for (const uint64_t cell: cells) {
			outfile << cell << endl;
		}
		outfile.close();

		// get live neighbor counts
		for (const auto& cell: grid.local_cells(neighborhood_id)) {
			(*cell.data)[1] = 0;
			for (const auto& neighbor: cell.neighbors_of) {
				if ((*neighbor.data)[0] == 1) {
					(*cell.data)[1]++;
				}
			}
		}

		// calculate the next turn
		for (const auto& cell: grid.local_cells(neighborhood_id)) {
			if ((*cell.data)[1] == 3) {
				(*cell.data)[0] = 1;
			} else if ((*cell.data)[1] != 2) {
				(*cell.data)[0] = 0;
			}
		}
	}

	MPI_Finalize();

	return EXIT_SUCCESS;
}
Exemplo n.º 2
0
int main(int argc, char* argv[])
{
	if (MPI_Init(&argc, &argv) != MPI_SUCCESS) {
		cerr << "Coudln't initialize MPI." << endl;
		abort();
	}

	MPI_Comm comm = MPI_COMM_WORLD;

	int rank = 0, comm_size = 0;
	MPI_Comm_rank(comm, &rank);
	MPI_Comm_size(comm, &comm_size);

	float zoltan_version;
	if (Zoltan_Initialize(argc, argv, &zoltan_version) != ZOLTAN_OK) {
	    cout << "Zoltan_Initialize failed" << endl;
	    exit(EXIT_FAILURE);
	}

	Dccrg<Cell, Stretched_Cartesian_Geometry> grid;

	constexpr size_t GRID_SIZE = 2;
	constexpr unsigned int NEIGHBORHOOD_SIZE = 1;
	grid
		.set_initial_length({GRID_SIZE, 1, 1})
		.set_neighborhood_length(NEIGHBORHOOD_SIZE)
		.set_maximum_refinement_level(-1)
		.set_load_balancing_method("RANDOM")
		.initialize(comm);

	constexpr double CELL_SIZE = 1.0 / GRID_SIZE;
	Stretched_Cartesian_Geometry::Parameters geom_params;
	for (size_t i = 0; i <= GRID_SIZE; i++) {
		geom_params.coordinates[0].push_back(i * CELL_SIZE);
	}
	geom_params.coordinates[1].push_back(0);
	geom_params.coordinates[1].push_back(0.5);
	geom_params.coordinates[2].push_back(0);
	geom_params.coordinates[2].push_back(0.5);
	grid.set_geometry(geom_params);

	// every process outputs the game state into its own file
	ostringstream basename, suffix(".vtk");
	basename << "refine_simple_" << rank << "_";
	ofstream outfile, visit_file;

	// visualize the game with visit -o game_of_life_test.visit
	if (rank == 0) {
		visit_file.open("tests/refine/refine_simple.visit");
		visit_file << "!NBLOCKS " << comm_size << endl;
	}

	constexpr size_t TIME_STEPS = 3;
	for (size_t step = 0; step < TIME_STEPS; step++) {

		// refine the smallest cell that is closest to the starting corner
		const std::array<double, 3> refine_coord{
			0.000001 * CELL_SIZE,
			0.000001 * CELL_SIZE,
			0.000001 * CELL_SIZE
		};
		grid.refine_completely_at(refine_coord);
		grid.stop_refining();
		grid.balance_load();
		auto cells = grid.get_cells();
		sort(cells.begin(), cells.end());

		for (const auto& cell: cells) {
			const auto ref_lvl = grid.get_refinement_level(cell);
			for (const auto& neighbor: *grid.get_neighbors_of(cell)) {
				if (neighbor.first == error_cell) {
					continue;
				}

				const auto neigh_ref_lvl = grid.get_refinement_level(neighbor.first);
				if (abs(ref_lvl - neigh_ref_lvl) > 1) {
					std::cerr << "Refinement level difference between " << cell
						<< " and " << neighbor.first << " too large" << std::endl;
					abort();
				}
			}
		}

		// write the game state into a file named according to the current time step
		string current_output_name("tests/refine/");
		ostringstream step_string;
		step_string.fill('0');
		step_string.width(5);
		step_string << step;
		current_output_name += basename.str();
		current_output_name += step_string.str();
		current_output_name += suffix.str();

		// visualize the game with visit -o game_of_life_test.visit
		if (rank == 0) {
			for (int process = 0; process < comm_size; process++) {
				visit_file << "refine_simple_" << process
					<< "_" << step_string.str() << suffix.str()
					<< endl;
			}
		}

		// write the grid into a file
		grid.write_vtk_file(current_output_name.c_str());
		// prepare to write the game data into the same file
		outfile.open(current_output_name.c_str(), ofstream::app);
		outfile << "CELL_DATA " << cells.size() << endl;

		// write each cells neighbor count
		outfile << "SCALARS neighbors int 1" << endl;
		outfile << "LOOKUP_TABLE default" << endl;
		for (const auto& cell: cells) {
			const auto* const neighbors = grid.get_neighbors_of(cell);
			outfile << neighbors->size() << endl;
		}

		// write each cells process
		outfile << "SCALARS process int 1" << endl;
		outfile << "LOOKUP_TABLE default" << endl;
		for (size_t i = 0; i < cells.size(); i++) {
			outfile << rank << endl;
		}

		// write each cells id
		outfile << "SCALARS id int 1" << endl;
		outfile << "LOOKUP_TABLE default" << endl;
		for (const auto& cell: cells) {
			outfile << cell << endl;
		}
		outfile.close();
	}

	if (rank == 0) {
		visit_file.close();
	}

	MPI_Finalize();

	return EXIT_SUCCESS;
}