<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: molecularSurfaceGrid.C,v 1.24 2005/12/23 17:03:03 amoll Exp $
//

#include <BALL/SOLVATION/molecularSurfaceGrid.h>
#include <BALL/KERNEL/forEach.h>

namespace BALL
{
	const char CCONN__INSIDE = 0;
	const char CCONN__OUTSIDE = 1;
	const char CCONN__INSIDE_PROBE = (char) 64;

	// needed for quicksort (below)
	extern "C" int
	#ifdef BALL_COMPILER_MSVC
	__cdecl
	#endif
	comparePointerSizeIntPtr_(const void* a, const void* b)
	{
		return (int)(*(PointerSizeUInt*)a - *(PointerSizeUInt*)b);
	}

	TRegularData3D<char>* calculateSESGrid
		(const Vector3& lower, const Vector3& upper,
		 float spacing, const System& system,
		 float probe_radius)
	{

		// points in the grid marked with

		PointerSizeUInt* fast_sphere;
		PointerSizeUInt* fast_sphere_relative;

		// contains the squared length of the diagonal distance in the grid
		float	d2, d;

		// contains the squared grid spacing
		float spacing2 = spacing * spacing;

		// the atom_radius
		float atom_radius;

		// The radius of the border points around an atom
		float R_b, R_b2;

		// the grid itself...
		TRegularData3D<char>	*grid;

		// squared distance of any two vectors
		float squared_distance;
		float x, y, z;
		Vector3 origin;

		// indices used in between to calculated the bounding boxes of spheres in the grid
		TRegularData3D<char>::IndexType upper_index;
		TRegularData3D<char>::IndexType lower_index;

		// pointer to grid data
		char* grid_value;

		// vector, describing the atom's coordinates
		Vector3 r0;

		// Here we go...
		// First, create the grid...
		grid = new TRegularData3D<char>(lower, upper - lower, Vector3(spacing));

		if (grid == 0)
		{
			return 0;
		}

		// ..then, calculate the grid's diagonal length
		d2 = spacing * spacing * spacing;
		d = sqrt(d2);

		// calculate some constants used for FAST access to the grid.
		origin = grid->getOrigin();

		// Nx is the number of points in the grid along the x-axis
		PointerSizeUInt Nx = grid->getSize().x;

		// Nxy is the number of points in an xy-plane
		PointerSizeUInt Nxy = Nx * grid->getSize().y;

		PointerSizeUInt i;
		PointerSizeUInt j;
		PointerSizeUInt k;

		// constructing the FAST probe sphere, a collection of points
		// of a sphere on the grid relative to the sphere's origin

		PointerSizeUInt count;
		PointerSizeUInt relative_count;

		// the probe_radius (squared) in squared grid units
		unsigned short grid_radius;
		grid_radius = (unsigned short)((probe_radius) * (probe_radius) / spacing2 + 0.5);
		count = 0;
		for (i = 0; i < (PointerSizeUInt)(probe_radius / spacing + 2); i++)
		{
			for (j = 0; j < (PointerSizeUInt)(probe_radius / spacing + 2); j++)
			{
				for (k = 0; k < (PointerSizeUInt)(probe_radius / spacing + 2); k++)
				{
					if ((i * i + j * j + k * k) < grid_radius)
					{
						count++;
					}
				}
			}
		}

		fast_sphere = new PointerSizeUInt[count * 8];
		fast_sphere_relative = new PointerSizeUInt[count * 8];

		count = 0;
		for (i = 0; i < (PointerSizeUInt)(probe_radius / spacing + 2); i++)
			for (j = 0; j < (PointerSizeUInt)(probe_radius / spacing + 2); j++)
					for (k = 0; k < (PointerSizeUInt)(probe_radius / spacing + 2); k++)
						if ((i * i + j * j + k * k) < grid_radius){
							fast_sphere[count++] =  (long)k + (long)j * (long)Nx + (long)i * (long)Nxy;
							fast_sphere[count++] = -(long)k + (long)j * (long)Nx + (long)i * (long)Nxy;
							fast_sphere[count++] =  (long)k - (long)j * (long)Nx + (long)i * (long)Nxy;
							fast_sphere[count++] = -(long)k - (long)j * (long)Nx + (long)i * (long)Nxy;
							fast_sphere[count++] =  (long)k + (long)j * (long)Nx - (long)i * (long)Nxy;
							fast_sphere[count++] = -(long)k + (long)j * (long)Nx - (long)i * (long)Nxy;
							fast_sphere[count++] =  (long)k - (long)j * (long)Nx - (long)i * (long)Nxy;
							fast_sphere[count++] = -(long)k - (long)j * (long)Nx - (long)i * (long)Nxy;
						}

		// now, for speed's sake, we sort the entries in fast_sphere
		qsort(fast_sphere, count, sizeof(long), comparePointerSizeIntPtr_);

		long last_index;
		relative_count = 1;
		last_index = fast_sphere[0];
		// loop variable
		PointerSizeUInt u;

		fast_sphere_relative[0] = fast_sphere[0];
		for (u = 1; u < count; u++){
			if (fast_sphere[u] != fast_sphere[u - 1]){
				fast_sphere_relative[relative_count] = fast_sphere[u] - last_index;
				last_index = fast_sphere[u];
				relative_count++;
			}
		}

		// throw away the original (unsorted) sphere data
		delete [] fast_sphere;

		// mark the whole grid with CCONN__OUTSIDE, meaning OUTSIDE
		// There will be three different marks: INSIDE(I), OUTSIDE(O), and BORDER(B)
		// BORDER is just used temporarily. In the end, The grid will just contain INSIDEs and OUTSIDEs

		memset((void*)&grid->getData(0), CCONN__OUTSIDE, grid->size() * sizeof(char));

		// for each atom do...
		AtomConstIterator	atom_iterator;
		BALL_FOREACH_ATOM(system, atom_iterator)
		{
			atom_radius = (*atom_iterator).getRadius();

			// consider the atom only if it`s radius is large
			// against grid spacing
			if (atom_radius > spacing / 100)
			{
				R_b = atom_radius + probe_radius;
				R_b2 = R_b * R_b;

				r0 = atom_iterator->getPosition();
				lower_index = grid->getClosestIndex(Vector3(r0.x - R_b - d, r0.y - R_b - d, r0.z - R_b - d));
				upper_index = grid->getClosestIndex(Vector3(r0.x + R_b + d, r0.y + R_b + d, r0.z + R_b + d));

				char* data = &(grid->getData(0));
				for(k = lower_index.z; k <= upper_index.z; k++)
					for(j = lower_index.y; j <= upper_index.y; j++)
						for(i = lower_index.x; i <= upper_index.x; i++){
							x = (float)i * spacing + origin.x;
							y = (float)j * spacing + origin.y;
							z = (float)k * spacing + origin.z;

							grid_value = &(data[i + Nx * j + Nxy * k]);

							if (*grid_value != CCONN__INSIDE)
							{
								squared_distance =  (r0.x - x) * (r0.x - x)
																 +  (r0.y - y) * (r0.y - y)
																 +  (r0.z - z) * (r0.z - z);
								if (squared_distance <= R_b2)
								{
									*grid_value = CCONN__INSIDE;
								}
							}
						}
			}
		}

		// now check for all points in the grid area that has been changed
		// for points marked as BORDER
		// If one of these points is found, remove all points marked INSIDE
		// which are less then probe_radius apart from the border point
		// (actually this means to "roll" the probe sphere along the border
		// and just retain points which haven't been touched by the probe sphere)
		PointerSizeUInt idx;
		PointerSizeUInt grid_pointer, grid_begin, grid_end;
		PointerSizeUInt* fast_sphere_end;
		PointerSizeUInt* sphere_pointer;

		unsigned short border;

		PointerSizeUInt border_count;
		border_count = 0;

		grid_begin = (PointerSizeUInt)grid->getData(0);
		grid_end = (PointerSizeUInt)grid->getData(grid->size());

		PointerSizeUInt s;
		PointerSizeUInt t;
		PointerSizeUInt q;

		char* data = &(grid->getData(0));
		for (s = 1; s < grid->getSize().z - 1; s++)
		{
			for (t = 1; t < grid->getSize().y - 1; t++)
			{
				for (q = 1; q < grid->getSize().x - 1; q++)
				{
					// calculate the absolute grid index the hard way (faster!)
					idx = q + Nx * t + s * Nxy;

					if ((data[idx] & 127) == CCONN__OUTSIDE)
					{
						border	= data[idx - 1]
										+ data[idx + 1]
										+ data[idx - Nx]
										+ data[idx + Nx]
										+ data[idx - Nxy]
										+ data[idx + Nxy];

						border &= 127;

						if ((border > 0) && (border < 6))
						{
							// Okay, we found a point on the boundary
							border_count++;
							grid_pointer = reinterpret_cast<PointerSizeUInt>(&(data[idx]));
							fast_sphere_end = &(fast_sphere_relative[relative_count - 1]);

							for (sphere_pointer = fast_sphere_relative; sphere_pointer <= fast_sphere_end; sphere_pointer++)
							{
								grid_pointer += static_cast<PointerSizeUInt>(*sphere_pointer);
								if ((grid_pointer <= grid_end) && (grid_pointer >= grid_begin))
								{
									*((char*)grid_pointer) |= CCONN__INSIDE_PROBE;
								}
							}
						}
					}
				}
			}
		}

		delete [] fast_sphere_relative;

		// now, check for each point if it is inside
		// A point is outside, if it has not been marked inside
		// (inside the vdW-radius) and has not been marked inside
		// the probe_radius of any border point

		grid_value = &(grid->getData(0));
		PointerSizeUInt l;

		for (l = 0; l < grid->size(); l++)
		{
			*grid_value = (*grid_value == 0);
			grid_value++;
		}

		return &(*grid);
	}

	TRegularData3D<char>* calculateSASGrid
		(const Vector3& lower, const Vector3& upper,
		 float spacing, const System& system, float probe_radius)
	{

		// points in the grid marked with
		// CCONN__OUTSIDE are outside of the molecule (default)
		// CCONN__INSIDE are sure inside the molecule

		// contains the squared length of the diagonal distance in the grid
		float	d2, d;

		// the atom_radius
		float atom_radius;

		// The radius of the border points around an atom
		float R_b, R_b2;

		// the grid itself...
		TRegularData3D<char>	*grid;

		// squared distance of any two vectors
		float squared_distance;
		float x, y, z;
		Vector3 origin;

		// indices used in between to calculated the bounding boxes of spheres in the grid
		TRegularData3D<char>::IndexType upper_index;
		TRegularData3D<char>::IndexType lower_index;

		// pointer to grid data
		char *grid_value;

		// vector, describing the atom's coordinates
		Vector3 r0;

		// Here we go...
		// First, create the grid...

		grid = new TRegularData3D<char>(lower, upper - lower, Vector3(spacing));

		if (grid == 0)
		{
			throw Exception::OutOfMemory(__FILE__, __LINE__);
		}

		// ..then, calculate the grid's diagonal length
		d2 = spacing * spacing * spacing;
		d = sqrt(d2);

		// calculate some constants used for FAST access to the grid.
		origin = grid->getOrigin();

		// Nx is the number of points in the grid along the x-axis
		PointerSizeUInt Nx = grid->getSize().x;

		// Nxy is the number of points in an xy-plane
		PointerSizeUInt Nxy = Nx * grid->getSize().y;

		// mark the whole grid with CCONN__OUTSIDE, meaning OUTSIDE
		// There will be three different marks: INSIDE(I), OUTSIDE(O), and BORDER(B)
		// BORDER is just used temporarily. In the end, The grid will just contain INSIDEs and OUTSIDEs

		memset((void*)&grid->getData(0), CCONN__OUTSIDE, grid->size() * sizeof(char));

		// for each atom do...
		char* data = &(grid->getData(0));
		AtomConstIterator	atom_iterator;
		BALL_FOREACH_ATOM(system, atom_iterator)
		{
			atom_radius = (*atom_iterator).getRadius();

			// consider the atom only if it`s radius is large
			// against grid spacing
			if (atom_radius > spacing / 100)
			{
				R_b = atom_radius + probe_radius;
				R_b2 = R_b * R_b;

				r0 = (*atom_iterator).getPosition();
				lower_index = grid->getClosestIndex(Vector3(r0.x - R_b - d, r0.y - R_b - d, r0.z - R_b - d));

				upper_index = grid->getClosestIndex(Vector3(r0.x + R_b + d, r0.y + R_b + d, r0.z + R_b + d));

				for (PointerSizeUInt k = lower_index.z; k <= upper_index.z; k++)
				{
					for (PointerSizeUInt j = lower_index.y; j <= upper_index.y; j++)
					{
						for (PointerSizeUInt i = lower_index.x; i <= upper_index.x; i++)
						{
							x = (float)i * spacing + origin.x;
							y = (float)j * spacing + origin.y;
							z = (float)k * spacing + origin.z;

							grid_value = &(data[i + Nx * j + Nxy * k]);

							if (*grid_value != CCONN__INSIDE)
							{
								squared_distance =  (r0.x - x) * (r0.x - x)
																 +  (r0.y - y) * (r0.y - y)
																 +  (r0.z - z) * (r0.z - z);

								if (squared_distance <= R_b2)
								{
									*grid_value = CCONN__INSIDE;
								}
							}
						}
					}
				}
			}
		}

		return &(*grid);
	}

} // namespace BALL
<commit_msg>Fix the calculation of the diagonal of a single grid cell of MolecularSurfaceGrid<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: molecularSurfaceGrid.C,v 1.24 2005/12/23 17:03:03 amoll Exp $
//

#include <BALL/SOLVATION/molecularSurfaceGrid.h>
#include <BALL/KERNEL/forEach.h>

namespace BALL
{
	const char CCONN__INSIDE = 0;
	const char CCONN__OUTSIDE = 1;
	const char CCONN__INSIDE_PROBE = (char) 64;

	// needed for quicksort (below)
	extern "C" int
	#ifdef BALL_COMPILER_MSVC
	__cdecl
	#endif
	comparePointerSizeIntPtr_(const void* a, const void* b)
	{
		return (int)(*(PointerSizeUInt*)a - *(PointerSizeUInt*)b);
	}

	TRegularData3D<char>* calculateSESGrid
		(const Vector3& lower, const Vector3& upper,
		 float spacing, const System& system,
		 float probe_radius)
	{

		// points in the grid marked with

		PointerSizeUInt* fast_sphere;
		PointerSizeUInt* fast_sphere_relative;

		// contains the squared length of the diagonal distance in the grid
		float d;

		// contains the squared grid spacing
		float spacing2 = spacing * spacing;

		// the atom_radius
		float atom_radius;

		// The radius of the border points around an atom
		float R_b, R_b2;

		// the grid itself...
		TRegularData3D<char>	*grid;

		// squared distance of any two vectors
		float squared_distance;
		float x, y, z;
		Vector3 origin;

		// indices used in between to calculated the bounding boxes of spheres in the grid
		TRegularData3D<char>::IndexType upper_index;
		TRegularData3D<char>::IndexType lower_index;

		// pointer to grid data
		char* grid_value;

		// vector, describing the atom's coordinates
		Vector3 r0;

		// Here we go...
		// First, create the grid...
		grid = new TRegularData3D<char>(lower, upper - lower, Vector3(spacing));

		if (grid == 0)
		{
			return 0;
		}

		// ..then, calculate the grid's diagonal length
		d = sqrt(3) * spacing;

		// calculate some constants used for FAST access to the grid.
		origin = grid->getOrigin();

		// Nx is the number of points in the grid along the x-axis
		PointerSizeUInt Nx = grid->getSize().x;

		// Nxy is the number of points in an xy-plane
		PointerSizeUInt Nxy = Nx * grid->getSize().y;

		PointerSizeUInt i;
		PointerSizeUInt j;
		PointerSizeUInt k;

		// constructing the FAST probe sphere, a collection of points
		// of a sphere on the grid relative to the sphere's origin

		PointerSizeUInt count;
		PointerSizeUInt relative_count;

		// the probe_radius (squared) in squared grid units
		unsigned short grid_radius;
		grid_radius = (unsigned short)((probe_radius) * (probe_radius) / spacing2 + 0.5);
		count = 0;
		for (i = 0; i < (PointerSizeUInt)(probe_radius / spacing + 2); i++)
		{
			for (j = 0; j < (PointerSizeUInt)(probe_radius / spacing + 2); j++)
			{
				for (k = 0; k < (PointerSizeUInt)(probe_radius / spacing + 2); k++)
				{
					if ((i * i + j * j + k * k) < grid_radius)
					{
						count++;
					}
				}
			}
		}

		fast_sphere = new PointerSizeUInt[count * 8];
		fast_sphere_relative = new PointerSizeUInt[count * 8];

		count = 0;
		for (i = 0; i < (PointerSizeUInt)(probe_radius / spacing + 2); i++)
			for (j = 0; j < (PointerSizeUInt)(probe_radius / spacing + 2); j++)
					for (k = 0; k < (PointerSizeUInt)(probe_radius / spacing + 2); k++)
						if ((i * i + j * j + k * k) < grid_radius){
							fast_sphere[count++] =  (long)k + (long)j * (long)Nx + (long)i * (long)Nxy;
							fast_sphere[count++] = -(long)k + (long)j * (long)Nx + (long)i * (long)Nxy;
							fast_sphere[count++] =  (long)k - (long)j * (long)Nx + (long)i * (long)Nxy;
							fast_sphere[count++] = -(long)k - (long)j * (long)Nx + (long)i * (long)Nxy;
							fast_sphere[count++] =  (long)k + (long)j * (long)Nx - (long)i * (long)Nxy;
							fast_sphere[count++] = -(long)k + (long)j * (long)Nx - (long)i * (long)Nxy;
							fast_sphere[count++] =  (long)k - (long)j * (long)Nx - (long)i * (long)Nxy;
							fast_sphere[count++] = -(long)k - (long)j * (long)Nx - (long)i * (long)Nxy;
						}

		// now, for speed's sake, we sort the entries in fast_sphere
		qsort(fast_sphere, count, sizeof(long), comparePointerSizeIntPtr_);

		long last_index;
		relative_count = 1;
		last_index = fast_sphere[0];
		// loop variable
		PointerSizeUInt u;

		fast_sphere_relative[0] = fast_sphere[0];
		for (u = 1; u < count; u++){
			if (fast_sphere[u] != fast_sphere[u - 1]){
				fast_sphere_relative[relative_count] = fast_sphere[u] - last_index;
				last_index = fast_sphere[u];
				relative_count++;
			}
		}

		// throw away the original (unsorted) sphere data
		delete [] fast_sphere;

		// mark the whole grid with CCONN__OUTSIDE, meaning OUTSIDE
		// There will be three different marks: INSIDE(I), OUTSIDE(O), and BORDER(B)
		// BORDER is just used temporarily. In the end, The grid will just contain INSIDEs and OUTSIDEs

		memset((void*)&grid->getData(0), CCONN__OUTSIDE, grid->size() * sizeof(char));

		// for each atom do...
		AtomConstIterator	atom_iterator;
		BALL_FOREACH_ATOM(system, atom_iterator)
		{
			atom_radius = (*atom_iterator).getRadius();

			// consider the atom only if it`s radius is large
			// against grid spacing
			if (atom_radius > spacing / 100)
			{
				R_b = atom_radius + probe_radius;
				R_b2 = R_b * R_b;

				r0 = atom_iterator->getPosition();
				lower_index = grid->getClosestIndex(Vector3(r0.x - R_b - d, r0.y - R_b - d, r0.z - R_b - d));
				upper_index = grid->getClosestIndex(Vector3(r0.x + R_b + d, r0.y + R_b + d, r0.z + R_b + d));

				char* data = &(grid->getData(0));
				for(k = lower_index.z; k <= upper_index.z; k++)
					for(j = lower_index.y; j <= upper_index.y; j++)
						for(i = lower_index.x; i <= upper_index.x; i++){
							x = (float)i * spacing + origin.x;
							y = (float)j * spacing + origin.y;
							z = (float)k * spacing + origin.z;

							grid_value = &(data[i + Nx * j + Nxy * k]);

							if (*grid_value != CCONN__INSIDE)
							{
								squared_distance =  (r0.x - x) * (r0.x - x)
																 +  (r0.y - y) * (r0.y - y)
																 +  (r0.z - z) * (r0.z - z);
								if (squared_distance <= R_b2)
								{
									*grid_value = CCONN__INSIDE;
								}
							}
						}
			}
		}

		// now check for all points in the grid area that has been changed
		// for points marked as BORDER
		// If one of these points is found, remove all points marked INSIDE
		// which are less then probe_radius apart from the border point
		// (actually this means to "roll" the probe sphere along the border
		// and just retain points which haven't been touched by the probe sphere)
		PointerSizeUInt idx;
		PointerSizeUInt grid_pointer, grid_begin, grid_end;
		PointerSizeUInt* fast_sphere_end;
		PointerSizeUInt* sphere_pointer;

		unsigned short border;

		PointerSizeUInt border_count;
		border_count = 0;

		grid_begin = (PointerSizeUInt)grid->getData(0);
		grid_end = (PointerSizeUInt)grid->getData(grid->size());

		PointerSizeUInt s;
		PointerSizeUInt t;
		PointerSizeUInt q;

		char* data = &(grid->getData(0));
		for (s = 1; s < grid->getSize().z - 1; s++)
		{
			for (t = 1; t < grid->getSize().y - 1; t++)
			{
				for (q = 1; q < grid->getSize().x - 1; q++)
				{
					// calculate the absolute grid index the hard way (faster!)
					idx = q + Nx * t + s * Nxy;

					if ((data[idx] & 127) == CCONN__OUTSIDE)
					{
						border	= data[idx - 1]
										+ data[idx + 1]
										+ data[idx - Nx]
										+ data[idx + Nx]
										+ data[idx - Nxy]
										+ data[idx + Nxy];

						border &= 127;

						if ((border > 0) && (border < 6))
						{
							// Okay, we found a point on the boundary
							border_count++;
							grid_pointer = reinterpret_cast<PointerSizeUInt>(&(data[idx]));
							fast_sphere_end = &(fast_sphere_relative[relative_count - 1]);

							for (sphere_pointer = fast_sphere_relative; sphere_pointer <= fast_sphere_end; sphere_pointer++)
							{
								grid_pointer += static_cast<PointerSizeUInt>(*sphere_pointer);
								if ((grid_pointer <= grid_end) && (grid_pointer >= grid_begin))
								{
									*((char*)grid_pointer) |= CCONN__INSIDE_PROBE;
								}
							}
						}
					}
				}
			}
		}

		delete [] fast_sphere_relative;

		// now, check for each point if it is inside
		// A point is outside, if it has not been marked inside
		// (inside the vdW-radius) and has not been marked inside
		// the probe_radius of any border point

		grid_value = &(grid->getData(0));
		PointerSizeUInt l;

		for (l = 0; l < grid->size(); l++)
		{
			*grid_value = (*grid_value == 0);
			grid_value++;
		}

		return &(*grid);
	}

	TRegularData3D<char>* calculateSASGrid
		(const Vector3& lower, const Vector3& upper,
		 float spacing, const System& system, float probe_radius)
	{

		// points in the grid marked with
		// CCONN__OUTSIDE are outside of the molecule (default)
		// CCONN__INSIDE are sure inside the molecule

		// contains the squared length of the diagonal distance in the grid
		float d;

		// the atom_radius
		float atom_radius;

		// The radius of the border points around an atom
		float R_b, R_b2;

		// the grid itself...
		TRegularData3D<char>	*grid;

		// squared distance of any two vectors
		float squared_distance;
		float x, y, z;
		Vector3 origin;

		// indices used in between to calculated the bounding boxes of spheres in the grid
		TRegularData3D<char>::IndexType upper_index;
		TRegularData3D<char>::IndexType lower_index;

		// pointer to grid data
		char *grid_value;

		// vector, describing the atom's coordinates
		Vector3 r0;

		// Here we go...
		// First, create the grid...

		grid = new TRegularData3D<char>(lower, upper - lower, Vector3(spacing));

		if (grid == 0)
		{
			throw Exception::OutOfMemory(__FILE__, __LINE__);
		}

		// ..then, calculate the grid's diagonal length
		d = sqrt(3) * spacing;

		// calculate some constants used for FAST access to the grid.
		origin = grid->getOrigin();

		// Nx is the number of points in the grid along the x-axis
		PointerSizeUInt Nx = grid->getSize().x;

		// Nxy is the number of points in an xy-plane
		PointerSizeUInt Nxy = Nx * grid->getSize().y;

		// mark the whole grid with CCONN__OUTSIDE, meaning OUTSIDE
		// There will be three different marks: INSIDE(I), OUTSIDE(O), and BORDER(B)
		// BORDER is just used temporarily. In the end, The grid will just contain INSIDEs and OUTSIDEs

		memset((void*)&grid->getData(0), CCONN__OUTSIDE, grid->size() * sizeof(char));

		// for each atom do...
		char* data = &(grid->getData(0));
		AtomConstIterator	atom_iterator;
		BALL_FOREACH_ATOM(system, atom_iterator)
		{
			atom_radius = (*atom_iterator).getRadius();

			// consider the atom only if it`s radius is large
			// against grid spacing
			if (atom_radius > spacing / 100)
			{
				R_b = atom_radius + probe_radius;
				R_b2 = R_b * R_b;

				r0 = (*atom_iterator).getPosition();
				lower_index = grid->getClosestIndex(Vector3(r0.x - R_b - d, r0.y - R_b - d, r0.z - R_b - d));

				upper_index = grid->getClosestIndex(Vector3(r0.x + R_b + d, r0.y + R_b + d, r0.z + R_b + d));

				for (PointerSizeUInt k = lower_index.z; k <= upper_index.z; k++)
				{
					for (PointerSizeUInt j = lower_index.y; j <= upper_index.y; j++)
					{
						for (PointerSizeUInt i = lower_index.x; i <= upper_index.x; i++)
						{
							x = (float)i * spacing + origin.x;
							y = (float)j * spacing + origin.y;
							z = (float)k * spacing + origin.z;

							grid_value = &(data[i + Nx * j + Nxy * k]);

							if (*grid_value != CCONN__INSIDE)
							{
								squared_distance =  (r0.x - x) * (r0.x - x)
																 +  (r0.y - y) * (r0.y - y)
																 +  (r0.z - z) * (r0.z - z);

								if (squared_distance <= R_b2)
								{
									*grid_value = CCONN__INSIDE;
								}
							}
						}
					}
				}
			}
		}

		return &(*grid);
	}

} // namespace BALL
<|endoftext|>


<commit_before>/*
  This file is part of KDE Kontact.

  Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
  Copyright (c) 2008 Allen Winter <winter@kde.org>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "kcmkontactsummary.h"
#include "plugin.h"

#include <kaboutdata.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kdialog.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kdemacros.h>
#include <kdeversion.h>
#include <kplugininfo.h>
#include <kservicetypetrader.h>
#include <kcomponentdata.h>

#include <QLabel>
#include <QVBoxLayout>
#include <QTreeWidgetItem>

extern "C"
{
  KDE_EXPORT KCModule *create_kontactsummary( QWidget *parent, const char * ) {
    KComponentData inst( "kcmkontactsummary" );
    return new KCMKontactSummary( inst, parent );
  }
}

class PluginItem : public QTreeWidgetItem
{
  public:
    PluginItem( const KPluginInfo &info, QTreeWidget *parent )
      : QTreeWidgetItem( parent ), mInfo( info )
    {
      setIcon( 0, KIcon( mInfo.icon() ) );
      setText( 0, mInfo.name() );
      setToolTip( 0, mInfo.comment() );
      setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
    }

    KPluginInfo pluginInfo() const
    {
      return mInfo;
    }

    virtual QString text( int column ) const
    {
      if ( column == 0 ) {
        return mInfo.name();
      } else if ( column == 1 ) {
        return mInfo.comment();
      } else {
        return QString();
      }
    }

  private:
    KPluginInfo mInfo;
};

PluginView::PluginView( QWidget *parent )
  : QTreeWidget( parent )
{
  setColumnCount( 1 );
  setHeaderLabel( i18nc( "@title:column plugin name", "Summary Plugin Name" ) );
}

PluginView::~PluginView()
{
}

KCMKontactSummary::KCMKontactSummary( const KComponentData &inst, QWidget *parent )
  : KCModule( inst, parent )
{
#if KDE_IS_VERSION(4,0,71 )
  setButtons( NoAdditionalButton );
#endif
  QVBoxLayout *layout = new QVBoxLayout( this );
  layout->setSpacing( KDialog::spacingHint() );
  layout->setMargin( 0 );

  QLabel *label =
    new QLabel( i18n( "Select the plugin summaries to show on the summary page." ), this );
  layout->addWidget( label );

  mPluginView = new PluginView( this );
  layout->addWidget( mPluginView );

  layout->setStretchFactor( mPluginView, 1 );

  load();

  KAboutData *about = new KAboutData( I18N_NOOP( "kontactsummary" ), 0,
                                      ki18n( "KDE Kontact Summary" ),
                                      0, KLocalizedString(), KAboutData::License_GPL,
                                      ki18n( "(c), 2004 Tobias Koenig" ) );

  about->addAuthor( ki18n( "Tobias Koenig" ), KLocalizedString(), "tokoe@kde.org" );
  setAboutData( about );
}

void KCMKontactSummary::load()
{
  KService::List offers = KServiceTypeTrader::self()->query(
      QString::fromLatin1( "Kontact/Plugin" ),
      QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );

  QStringList activeSummaries;

  KConfig config( "kontact_summaryrc" );
  KConfigGroup grp( &config, QString() );
  if ( !grp.hasKey( "ActiveSummaries" ) ) {
    activeSummaries << "kontact_kaddressbookplugin";
    activeSummaries << "kontact_specialdatesplugin";
    activeSummaries << "kontact_korganizerplugin";
    activeSummaries << "kontact_todoplugin";
    activeSummaries << "kontact_knotesplugin";
    activeSummaries << "kontact_kmailplugin";
    activeSummaries << "kontact_weatherplugin";
    activeSummaries << "kontact_newstickerplugin";
    activeSummaries << "kontact_plannerplugin";
  } else {
    activeSummaries = grp.readEntry( "ActiveSummaries", QStringList() );
  }

  mPluginView->clear();

  KPluginInfo::List pluginList =
    KPluginInfo::fromServices( offers, KConfigGroup( &config, "Plugins" ) );
  KPluginInfo::List::Iterator it;
  for ( it = pluginList.begin(); it != pluginList.end(); ++it ) {
    it->load();

    if ( !it->isPluginEnabled() ) {
      continue;
    }

    QVariant var = it->property( "X-KDE-KontactPluginHasSummary" );
    if ( var.isValid() && var.toBool() == true ) {
      PluginItem *item = new PluginItem( *it, mPluginView );

      if ( activeSummaries.contains( it->pluginName() ) ) {
        item->setCheckState( 0, Qt::Checked );
      } else {
        item->setCheckState( 0, Qt::Unchecked );
      }
    }
  }
}

void KCMKontactSummary::save()
{
  kDebug();
  QStringList activeSummaries;

  QTreeWidgetItemIterator it( mPluginView );
  while ( *it ) {
    PluginItem *item = static_cast<PluginItem *>( *it );
    if ( item->checkState( 0 ) == Qt::Checked ) {
      activeSummaries.append( item->pluginInfo().pluginName() );
    }
    ++it;
  }

  KConfig config( "kontact_summaryrc" );
  KConfigGroup grp( &config, QString() );
  kDebug() << "saving activesummaries " << activeSummaries;
  grp.writeEntry( "ActiveSummaries", activeSummaries );
}

#include "kcmkontactsummary.moc"
<commit_msg>Enable the apply button when the user check/unchecks a plugin. Also, changes are saved now.<commit_after>/*
  This file is part of KDE Kontact.

  Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
  Copyright (c) 2008 Allen Winter <winter@kde.org>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "kcmkontactsummary.h"
#include "plugin.h"

#include <kaboutdata.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kdialog.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kdemacros.h>
#include <kdeversion.h>
#include <kplugininfo.h>
#include <kservicetypetrader.h>
#include <kcomponentdata.h>

#include <QLabel>
#include <QVBoxLayout>
#include <QTreeWidgetItem>

extern "C"
{
  KDE_EXPORT KCModule *create_kontactsummary( QWidget *parent, const char * ) {
    KComponentData inst( "kcmkontactsummary" );
    return new KCMKontactSummary( inst, parent );
  }
}

class PluginItem : public QTreeWidgetItem
{
  public:
    PluginItem( const KPluginInfo &info, QTreeWidget *parent )
      : QTreeWidgetItem( parent ), mInfo( info )
    {
      setIcon( 0, KIcon( mInfo.icon() ) );
      setText( 0, mInfo.name() );
      setToolTip( 0, mInfo.comment() );
      setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
    }

    KPluginInfo pluginInfo() const
    {
      return mInfo;
    }

    virtual QString text( int column ) const
    {
      if ( column == 0 ) {
        return mInfo.name();
      } else if ( column == 1 ) {
        return mInfo.comment();
      } else {
        return QString();
      }
    }

  private:
    KPluginInfo mInfo;
};

PluginView::PluginView( QWidget *parent )
  : QTreeWidget( parent )
{
  setColumnCount( 1 );
  setHeaderLabel( i18nc( "@title:column plugin name", "Summary Plugin Name" ) );
}

PluginView::~PluginView()
{
}

KCMKontactSummary::KCMKontactSummary( const KComponentData &inst, QWidget *parent )
  : KCModule( inst, parent )
{
#if KDE_IS_VERSION(4,0,71 )
  setButtons( NoAdditionalButton );
#endif
  QVBoxLayout *layout = new QVBoxLayout( this );
  layout->setSpacing( KDialog::spacingHint() );
  layout->setMargin( 0 );

  QLabel *label =
    new QLabel( i18n( "Select the plugin summaries to show on the summary page." ), this );
  layout->addWidget( label );

  mPluginView = new PluginView( this );
  layout->addWidget( mPluginView );

  layout->setStretchFactor( mPluginView, 1 );

  load();
  connect( mPluginView, SIGNAL( itemChanged( QTreeWidgetItem *, int ) ),
           this, SLOT( changed() ) );

  KAboutData *about = new KAboutData( I18N_NOOP( "kontactsummary" ), 0,
                                      ki18n( "KDE Kontact Summary" ),
                                      0, KLocalizedString(), KAboutData::License_GPL,
                                      ki18n( "(c), 2004 Tobias Koenig" ) );

  about->addAuthor( ki18n( "Tobias Koenig" ), KLocalizedString(), "tokoe@kde.org" );
  setAboutData( about );
}

void KCMKontactSummary::load()
{
  KService::List offers = KServiceTypeTrader::self()->query(
      QString::fromLatin1( "Kontact/Plugin" ),
      QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );

  QStringList activeSummaries;

  KConfig config( "kontact_summaryrc" );
  KConfigGroup grp( &config, QString() );
  if ( !grp.hasKey( "ActiveSummaries" ) ) {
    activeSummaries << "kontact_kaddressbookplugin";
    activeSummaries << "kontact_specialdatesplugin";
    activeSummaries << "kontact_korganizerplugin";
    activeSummaries << "kontact_todoplugin";
    activeSummaries << "kontact_knotesplugin";
    activeSummaries << "kontact_kmailplugin";
    activeSummaries << "kontact_weatherplugin";
    activeSummaries << "kontact_newstickerplugin";
    activeSummaries << "kontact_plannerplugin";
  } else {
    activeSummaries = grp.readEntry( "ActiveSummaries", QStringList() );
  }

  mPluginView->clear();

  KPluginInfo::List pluginList =
    KPluginInfo::fromServices( offers, KConfigGroup( &config, "Plugins" ) );
  KPluginInfo::List::Iterator it;
  for ( it = pluginList.begin(); it != pluginList.end(); ++it ) {
    it->load();

    if ( !it->isPluginEnabled() ) {
      continue;
    }

    QVariant var = it->property( "X-KDE-KontactPluginHasSummary" );
    if ( var.isValid() && var.toBool() == true ) {
      PluginItem *item = new PluginItem( *it, mPluginView );

      if ( activeSummaries.contains( it->pluginName() ) ) {
        item->setCheckState( 0, Qt::Checked );
      } else {
        item->setCheckState( 0, Qt::Unchecked );
      }
    }
  }
}

void KCMKontactSummary::save()
{
  kDebug();
  QStringList activeSummaries;

  QTreeWidgetItemIterator it( mPluginView );
  while ( *it ) {
    PluginItem *item = static_cast<PluginItem *>( *it );
    if ( item->checkState( 0 ) == Qt::Checked ) {
      activeSummaries.append( item->pluginInfo().pluginName() );
    }
    ++it;
  }

  KConfig config( "kontact_summaryrc" );
  KConfigGroup grp( &config, QString() );
  kDebug() << "saving activesummaries " << activeSummaries;
  grp.writeEntry( "ActiveSummaries", activeSummaries );
}

#include "kcmkontactsummary.moc"
<|endoftext|>


<commit_before>#include "entity_id.h"

#include "world.h"
#include "halley/maths/uuid.h"
#include "halley/entity/entity_factory.h"

using namespace Halley;

String EntityId::toUUID(const EntityId& id, ConfigNodeSerializationContext& context)
{
	auto& world = context.entityContext->world;
	return world.getEntity(id).getInstanceUUID().toString();
}

EntityId EntityId::fromUUID(const String& uuidStr, ConfigNodeSerializationContext& context)
{
	const auto iter = context.entityContext->uuids.find(UUID(uuidStr));
	if (iter != context.entityContext->uuids.end()) {
		return iter->second;
	}

	const auto& prefabIter = context.entityContext->uuidMapping.back().find(UUID(uuidStr));
	if (prefabIter != context.entityContext->uuidMapping.back().end()) {
		const auto& instanceIter = context.entityContext->uuids.find(prefabIter->second);
		if (instanceIter != context.entityContext->uuids.end()) {
			return instanceIter->second;
		}
	}

	return EntityId();
}
<commit_msg>Temporarily disable UUID -> EntityId mapping<commit_after>#include "entity_id.h"

#include "world.h"
#include "halley/maths/uuid.h"
#include "halley/entity/entity_factory.h"

using namespace Halley;

String EntityId::toUUID(const EntityId& id, ConfigNodeSerializationContext& context)
{
	auto& world = context.entityContext->world;
	return world.getEntity(id).getInstanceUUID().toString();
}

EntityId EntityId::fromUUID(const String& uuidStr, ConfigNodeSerializationContext& context)
{
	/*
	const auto iter = context.entityContext->uuids.find(UUID(uuidStr));
	if (iter != context.entityContext->uuids.end()) {
		return iter->second;
	}

	const auto& prefabIter = context.entityContext->uuidMapping.back().find(UUID(uuidStr));
	if (prefabIter != context.entityContext->uuidMapping.back().end()) {
		const auto& instanceIter = context.entityContext->uuids.find(prefabIter->second);
		if (instanceIter != context.entityContext->uuids.end()) {
			return instanceIter->second;
		}
	}
	*/

	return EntityId();
}
<|endoftext|>


<commit_before>//==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines a checkers that display debugging information.
//
//===----------------------------------------------------------------------===//

#include "ClangSACheckers.h"
#include "clang/Analysis/Analyses/Dominators.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/CallGraph.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "llvm/Support/Process.h"

using namespace clang;
using namespace ento;

//===----------------------------------------------------------------------===//
// DominatorsTreeDumper
//===----------------------------------------------------------------------===//

namespace {
class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
public:
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                        BugReporter &BR) const {
    if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
      DominatorTree dom;
      dom.buildDominatorTree(*AC);
      dom.dump();
    }
  }
};
}

void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
  mgr.registerChecker<DominatorsTreeDumper>();
}

//===----------------------------------------------------------------------===//
// LiveVariablesDumper
//===----------------------------------------------------------------------===//

namespace {
class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
public:
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                        BugReporter &BR) const {
    if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) {
      L->dumpBlockLiveness(mgr.getSourceManager());
    }
  }
};
}

void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
  mgr.registerChecker<LiveVariablesDumper>();
}

//===----------------------------------------------------------------------===//
// CFGViewer
//===----------------------------------------------------------------------===//

namespace {
class CFGViewer : public Checker<check::ASTCodeBody> {
public:
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                        BugReporter &BR) const {
    if (CFG *cfg = mgr.getCFG(D)) {
      cfg->viewCFG(mgr.getLangOpts());
    }
  }
};
}

void ento::registerCFGViewer(CheckerManager &mgr) {
  mgr.registerChecker<CFGViewer>();
}

//===----------------------------------------------------------------------===//
// CFGDumper
//===----------------------------------------------------------------------===//

namespace {
class CFGDumper : public Checker<check::ASTCodeBody> {
public:
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                        BugReporter &BR) const {
    if (CFG *cfg = mgr.getCFG(D)) {
      cfg->dump(mgr.getLangOpts(),
                llvm::sys::Process::StandardErrHasColors());
    }
  }
};
}

void ento::registerCFGDumper(CheckerManager &mgr) {
  mgr.registerChecker<CFGDumper>();
}

//===----------------------------------------------------------------------===//
// CallGraphViewer
//===----------------------------------------------------------------------===//

namespace {
class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
public:
  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
                    BugReporter &BR) const {
    CallGraph CG;
    CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
    CG.viewGraph();
  }
};
}

void ento::registerCallGraphViewer(CheckerManager &mgr) {
  mgr.registerChecker<CallGraphViewer>();
}

//===----------------------------------------------------------------------===//
// CallGraphDumper
//===----------------------------------------------------------------------===//

namespace {
class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
public:
  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
                    BugReporter &BR) const {
    CallGraph CG;
    CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
    CG.dump();
  }
};
}

void ento::registerCallGraphDumper(CheckerManager &mgr) {
  mgr.registerChecker<CallGraphDumper>();
}

//===----------------------------------------------------------------------===//
// ConfigDumper
//===----------------------------------------------------------------------===//

namespace {
class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
public:
  void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
                                 AnalysisManager& mgr,
                                 BugReporter &BR) const {

    const AnalyzerOptions::ConfigTable &Config = mgr.options.Config;
    AnalyzerOptions::ConfigTable::const_iterator I =
      Config.begin(), E = Config.end();

    std::vector<StringRef> Keys;
    for (; I != E ; ++I) { Keys.push_back(I->getKey()); }
    sort(Keys.begin(), Keys.end());

    llvm::errs() << "[config]\n";
    for (unsigned i = 0, n = Keys.size(); i < n ; ++i) {
      StringRef Key = Keys[i];
      I = Config.find(Key);
      llvm::errs() << Key << " = " << I->second << '\n';
    }
    llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
  }
};
}

void ento::registerConfigDumper(CheckerManager &mgr) {
  mgr.registerChecker<ConfigDumper>();
}
<commit_msg>[analyzer] Fix grammar in comment.<commit_after>//==- DebugCheckers.cpp - Debugging Checkers ---------------------*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines checkers that display debugging information.
//
//===----------------------------------------------------------------------===//

#include "ClangSACheckers.h"
#include "clang/Analysis/Analyses/Dominators.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/CallGraph.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "llvm/Support/Process.h"

using namespace clang;
using namespace ento;

//===----------------------------------------------------------------------===//
// DominatorsTreeDumper
//===----------------------------------------------------------------------===//

namespace {
class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {
public:
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                        BugReporter &BR) const {
    if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
      DominatorTree dom;
      dom.buildDominatorTree(*AC);
      dom.dump();
    }
  }
};
}

void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
  mgr.registerChecker<DominatorsTreeDumper>();
}

//===----------------------------------------------------------------------===//
// LiveVariablesDumper
//===----------------------------------------------------------------------===//

namespace {
class LiveVariablesDumper : public Checker<check::ASTCodeBody> {
public:
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                        BugReporter &BR) const {
    if (LiveVariables* L = mgr.getAnalysis<LiveVariables>(D)) {
      L->dumpBlockLiveness(mgr.getSourceManager());
    }
  }
};
}

void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
  mgr.registerChecker<LiveVariablesDumper>();
}

//===----------------------------------------------------------------------===//
// CFGViewer
//===----------------------------------------------------------------------===//

namespace {
class CFGViewer : public Checker<check::ASTCodeBody> {
public:
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                        BugReporter &BR) const {
    if (CFG *cfg = mgr.getCFG(D)) {
      cfg->viewCFG(mgr.getLangOpts());
    }
  }
};
}

void ento::registerCFGViewer(CheckerManager &mgr) {
  mgr.registerChecker<CFGViewer>();
}

//===----------------------------------------------------------------------===//
// CFGDumper
//===----------------------------------------------------------------------===//

namespace {
class CFGDumper : public Checker<check::ASTCodeBody> {
public:
  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                        BugReporter &BR) const {
    if (CFG *cfg = mgr.getCFG(D)) {
      cfg->dump(mgr.getLangOpts(),
                llvm::sys::Process::StandardErrHasColors());
    }
  }
};
}

void ento::registerCFGDumper(CheckerManager &mgr) {
  mgr.registerChecker<CFGDumper>();
}

//===----------------------------------------------------------------------===//
// CallGraphViewer
//===----------------------------------------------------------------------===//

namespace {
class CallGraphViewer : public Checker< check::ASTDecl<TranslationUnitDecl> > {
public:
  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
                    BugReporter &BR) const {
    CallGraph CG;
    CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
    CG.viewGraph();
  }
};
}

void ento::registerCallGraphViewer(CheckerManager &mgr) {
  mgr.registerChecker<CallGraphViewer>();
}

//===----------------------------------------------------------------------===//
// CallGraphDumper
//===----------------------------------------------------------------------===//

namespace {
class CallGraphDumper : public Checker< check::ASTDecl<TranslationUnitDecl> > {
public:
  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr,
                    BugReporter &BR) const {
    CallGraph CG;
    CG.addToCallGraph(const_cast<TranslationUnitDecl*>(TU));
    CG.dump();
  }
};
}

void ento::registerCallGraphDumper(CheckerManager &mgr) {
  mgr.registerChecker<CallGraphDumper>();
}

//===----------------------------------------------------------------------===//
// ConfigDumper
//===----------------------------------------------------------------------===//

namespace {
class ConfigDumper : public Checker< check::EndOfTranslationUnit > {
public:
  void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
                                 AnalysisManager& mgr,
                                 BugReporter &BR) const {

    const AnalyzerOptions::ConfigTable &Config = mgr.options.Config;
    AnalyzerOptions::ConfigTable::const_iterator I =
      Config.begin(), E = Config.end();

    std::vector<StringRef> Keys;
    for (; I != E ; ++I) { Keys.push_back(I->getKey()); }
    sort(Keys.begin(), Keys.end());

    llvm::errs() << "[config]\n";
    for (unsigned i = 0, n = Keys.size(); i < n ; ++i) {
      StringRef Key = Keys[i];
      I = Config.find(Key);
      llvm::errs() << Key << " = " << I->second << '\n';
    }
    llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n';
  }
};
}

void ento::registerConfigDumper(CheckerManager &mgr) {
  mgr.registerChecker<ConfigDumper>();
}
<|endoftext|>


<commit_before>/**
 * Copyright 2011 Tim Simpson
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef MACARONI_MODEL_CPP_FUNCTIONOVERLOAD_CPP
#define MACARONI_MODEL_CPP_FUNCTIONOVERLOAD_CPP

#include "FunctionOverload.h"
#include <boost/format.hpp>
#include <Macaroni/Model/ModelInconsistencyException.h>
#include <Macaroni/Model/Reason.h>
#include <Macaroni/Model/Source.h>
#include <Macaroni/Model/Cpp/Variable.h>

using Macaroni::Model::ModelInconsistencyException;
using boost::optional;
using Macaroni::Model::Project::TargetPtr;

BEGIN_NAMESPACE(Macaroni, Model, Cpp)

FunctionOverload::FunctionOverload
(
 Node * home, Model::ReasonPtr reason, bool isInline,
 Access access, const bool isStatic, bool isVirtual,
 const TypePtr rtnTypeInfo, bool constMember,
 const optional<ExceptionSpecifier> exceptionSpecifier
)
:ScopeMember(home, "FunctionOverload",
			 reason, access, isStatic),
 codeBlock(),
 codeBlockAddRedirect(false),
 constMember(constMember),
 isInline(isInline),
 isPureVirtual(false),
 isVirtual(isVirtual),
 returnType(rtnTypeInfo),
 exceptionSpecifier(exceptionSpecifier),
 usesDefaultKeyword(false),
 usesDeleteKeyword(false)
{
}

FunctionOverload::FunctionOverload
(
 Node * home, const char * typeName, Model::ReasonPtr reason, bool isInline,
 Access access, const bool isStatic, bool isVirtual,
 const TypePtr rtnTypeInfo, bool constMember,
 const optional<ExceptionSpecifier> exceptionSpecifier
)
:ScopeMember(home, typeName,
			 reason, access, isStatic),
 codeBlock(),
 constMember(constMember),
 codeSource(),
 isInline(isInline),
 isPureVirtual(false),
 isVirtual(isVirtual),
 returnType(rtnTypeInfo),
 exceptionSpecifier(exceptionSpecifier),
 usesDefaultKeyword(false),
 usesDeleteKeyword(false)
{
}

FunctionOverload::~FunctionOverload()
{
}

FunctionOverloadPtr FunctionOverload::Create(FunctionPtr home,
											 bool isInline, const AccessPtr access,
											 const bool isStatic,
											 bool isVirtual,
											 const TypePtr rtnType,
											 bool constMember,
						  const optional<ExceptionSpecifier> exceptionSpecifier,
											 Model::ReasonPtr reason)
{
	Function * fn = home.get();
	return Create(fn, isInline, access, isStatic, isVirtual, rtnType,
		          constMember, exceptionSpecifier, reason);
}

FunctionOverloadPtr FunctionOverload::Create(Function * fn,
											 bool isInline, const AccessPtr access,
											 const bool isStatic,
											 bool isVirtual,
											 const TypePtr rtnType,
											 bool constMember,
						  const optional<ExceptionSpecifier> exceptionSpecifier,
											 Model::ReasonPtr reason)
{
	Node * node = fn->GetNode().get();
	NodePtr foNode = node->CreateNextInSequence("Overload#");
	return Create(foNode, isInline, access, isStatic, isVirtual, rtnType,
		          constMember, exceptionSpecifier, reason);
}

FunctionOverloadPtr FunctionOverload::Create(NodePtr foNode,
											 bool isInline, const AccessPtr access,
											 const bool isStatic,
											 bool isVirtual,
											 const TypePtr rtnType,
											 bool constMember,
						const optional<ExceptionSpecifier> exceptionSpecifier,
											 Model::ReasonPtr reason)
{
	FunctionOverload * fo = new FunctionOverload(foNode.get(), reason,
		isInline, *access,
		isStatic, isVirtual, rtnType, constMember, exceptionSpecifier);
	return FunctionOverloadPtr(fo);
}

bool FunctionOverload::canBeChildOf(const Member * other) const
{
	return dynamic_cast<const Function *>(other) != nullptr;
}

bool FunctionOverload::DoesDefinitionReference(NodePtr node) const
{
	return this->returnType->GetNode() == node ? true
		: this->Member::DoesDefinitionReference(node);
}

NodeListPtr FunctionOverload::GetArguments() const
{
	NodeListPtr argList(new NodeList());
	NodeListPtr args(new NodeList());
	for (unsigned int i = 0; i < getNode()->GetChildCount(); i ++)
	{
		NodePtr child = getNode()->GetChild(i);
		ElementPtr element = child->GetElement();
		if (element && nullptr != boost::dynamic_pointer_cast<Variable>(element))
		{
			argList->push_back(child);
		}
		MACARONI_ASSERT(!!child->GetElement(), "Member for function argument set to null.");
		ElementPtr element = child->GetElement();
		MACARONI_ASSERT(boost::dynamic_pointer_cast<Variable>(element),
					"Member was not of type variable - code is out of date.");
		argList->push_back(child);
	}
	return argList;
}

const std::string & FunctionOverload::GetCodeBlock() const
{
	return codeBlock;
}

const char * FunctionOverload::GetTypeName() const
{
	return "FunctionOverload";
}

bool FunctionOverload::HasCodeBlock() const
{
	return (!!codeSource);
}

void intrusive_ptr_add_ref(FunctionOverload * p)
{
	intrusive_ptr_add_ref((ScopeMember *)p);
}

void intrusive_ptr_release(FunctionOverload * p)
{
	intrusive_ptr_release((ScopeMember *)p);
}

bool FunctionOverload::RequiresCppFile() const
{
	return HasCodeBlock() && !(
		IsInline() || IsPureVirtual() || UsesDefault() || IsDeleted()
	);
}

bool FunctionOverload::RequiresHFile() const
{
	return getAccess().VisibleInHeader();
}

void FunctionOverload::SetCodeBlock(std::string & code, SourcePtr startOfCode,
									bool codeBlockAddRedirect)
{
	setCodeDefinitionSource(startOfCode,
		"Cannot create a code block for function %s because one was "
		"already defined at %s.");
	codeBlock = code;
	this->codeBlockAddRedirect = codeBlockAddRedirect;
}

void FunctionOverload::SetDefault(SourcePtr startOfCode)
{
	setCodeDefinitionSource(startOfCode,
		"Cannot set function %s to use the default keyword because it already "
		"was defined at %s.");
	this->codeSource = startOfCode;
	this->usesDefaultKeyword = true;
}

void FunctionOverload::SetDelete(SourcePtr startOfCode)
{
	setCodeDefinitionSource(startOfCode,
		"Cannot set function %s to use the delete keyword because it already "
		"was defined at %s.");
	this->codeSource = startOfCode;
	this->usesDeleteKeyword = true;
}

void FunctionOverload::SetPureVirtual(SourcePtr startOfCode)
{
	setCodeDefinitionSource(startOfCode,
		"Cannot set function %s as pure virtual because it already "
		"was defined at %s.");
	this->codeSource = startOfCode;
	this->isPureVirtual = true;
}

void FunctionOverload::setCodeDefinitionSource(SourcePtr startOfCode,
	                                           const char * const msg)
{
	if (!!codeSource)
	{
		std::string text = str(boost::format(msg)
			% this->getNode()->GetFullName() % codeSource->ToString());
		throw ModelInconsistencyException(startOfCode, text);
	}
	this->codeSource = startOfCode;
}

END_NAMESPACE

#endif
<commit_msg>Adds fix that missed the last commit<commit_after>/**
 * Copyright 2011 Tim Simpson
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef MACARONI_MODEL_CPP_FUNCTIONOVERLOAD_CPP
#define MACARONI_MODEL_CPP_FUNCTIONOVERLOAD_CPP

#include "FunctionOverload.h"
#include <boost/format.hpp>
#include <Macaroni/Model/ModelInconsistencyException.h>
#include <Macaroni/Model/Reason.h>
#include <Macaroni/Model/Source.h>
#include <Macaroni/Model/Cpp/Variable.h>

using Macaroni::Model::ModelInconsistencyException;
using boost::optional;
using Macaroni::Model::Project::TargetPtr;

BEGIN_NAMESPACE(Macaroni, Model, Cpp)

FunctionOverload::FunctionOverload
(
 Node * home, Model::ReasonPtr reason, bool isInline,
 Access access, const bool isStatic, bool isVirtual,
 const TypePtr rtnTypeInfo, bool constMember,
 const optional<ExceptionSpecifier> exceptionSpecifier
)
:ScopeMember(home, "FunctionOverload",
			 reason, access, isStatic),
 codeBlock(),
 codeBlockAddRedirect(false),
 constMember(constMember),
 isInline(isInline),
 isPureVirtual(false),
 isVirtual(isVirtual),
 returnType(rtnTypeInfo),
 exceptionSpecifier(exceptionSpecifier),
 usesDefaultKeyword(false),
 usesDeleteKeyword(false)
{
}

FunctionOverload::FunctionOverload
(
 Node * home, const char * typeName, Model::ReasonPtr reason, bool isInline,
 Access access, const bool isStatic, bool isVirtual,
 const TypePtr rtnTypeInfo, bool constMember,
 const optional<ExceptionSpecifier> exceptionSpecifier
)
:ScopeMember(home, typeName,
			 reason, access, isStatic),
 codeBlock(),
 constMember(constMember),
 codeSource(),
 isInline(isInline),
 isPureVirtual(false),
 isVirtual(isVirtual),
 returnType(rtnTypeInfo),
 exceptionSpecifier(exceptionSpecifier),
 usesDefaultKeyword(false),
 usesDeleteKeyword(false)
{
}

FunctionOverload::~FunctionOverload()
{
}

FunctionOverloadPtr FunctionOverload::Create(FunctionPtr home,
											 bool isInline, const AccessPtr access,
											 const bool isStatic,
											 bool isVirtual,
											 const TypePtr rtnType,
											 bool constMember,
						  const optional<ExceptionSpecifier> exceptionSpecifier,
											 Model::ReasonPtr reason)
{
	Function * fn = home.get();
	return Create(fn, isInline, access, isStatic, isVirtual, rtnType,
		          constMember, exceptionSpecifier, reason);
}

FunctionOverloadPtr FunctionOverload::Create(Function * fn,
											 bool isInline, const AccessPtr access,
											 const bool isStatic,
											 bool isVirtual,
											 const TypePtr rtnType,
											 bool constMember,
						  const optional<ExceptionSpecifier> exceptionSpecifier,
											 Model::ReasonPtr reason)
{
	Node * node = fn->GetNode().get();
	NodePtr foNode = node->CreateNextInSequence("Overload#");
	return Create(foNode, isInline, access, isStatic, isVirtual, rtnType,
		          constMember, exceptionSpecifier, reason);
}

FunctionOverloadPtr FunctionOverload::Create(NodePtr foNode,
											 bool isInline, const AccessPtr access,
											 const bool isStatic,
											 bool isVirtual,
											 const TypePtr rtnType,
											 bool constMember,
						const optional<ExceptionSpecifier> exceptionSpecifier,
											 Model::ReasonPtr reason)
{
	FunctionOverload * fo = new FunctionOverload(foNode.get(), reason,
		isInline, *access,
		isStatic, isVirtual, rtnType, constMember, exceptionSpecifier);
	return FunctionOverloadPtr(fo);
}

bool FunctionOverload::canBeChildOf(const Member * other) const
{
	return dynamic_cast<const Function *>(other) != nullptr;
}

bool FunctionOverload::DoesDefinitionReference(NodePtr node) const
{
	return this->returnType->GetNode() == node ? true
		: this->Member::DoesDefinitionReference(node);
}

NodeListPtr FunctionOverload::GetArguments() const
{
	NodeListPtr argList(new NodeList());
	NodeListPtr args(new NodeList());
	for (unsigned int i = 0; i < getNode()->GetChildCount(); i ++)
	{
		NodePtr child = getNode()->GetChild(i);
		ElementPtr element = child->GetElement();
		if (element && nullptr != boost::dynamic_pointer_cast<Variable>(element))
		{
			argList->push_back(child);
		}
	}
	return argList;
}

const std::string & FunctionOverload::GetCodeBlock() const
{
	return codeBlock;
}

const char * FunctionOverload::GetTypeName() const
{
	return "FunctionOverload";
}

bool FunctionOverload::HasCodeBlock() const
{
	return (!!codeSource);
}

void intrusive_ptr_add_ref(FunctionOverload * p)
{
	intrusive_ptr_add_ref((ScopeMember *)p);
}

void intrusive_ptr_release(FunctionOverload * p)
{
	intrusive_ptr_release((ScopeMember *)p);
}

bool FunctionOverload::RequiresCppFile() const
{
	return HasCodeBlock() && !(
		IsInline() || IsPureVirtual() || UsesDefault() || IsDeleted()
	);
}

bool FunctionOverload::RequiresHFile() const
{
	return getAccess().VisibleInHeader();
}

void FunctionOverload::SetCodeBlock(std::string & code, SourcePtr startOfCode,
									bool codeBlockAddRedirect)
{
	setCodeDefinitionSource(startOfCode,
		"Cannot create a code block for function %s because one was "
		"already defined at %s.");
	codeBlock = code;
	this->codeBlockAddRedirect = codeBlockAddRedirect;
}

void FunctionOverload::SetDefault(SourcePtr startOfCode)
{
	setCodeDefinitionSource(startOfCode,
		"Cannot set function %s to use the default keyword because it already "
		"was defined at %s.");
	this->codeSource = startOfCode;
	this->usesDefaultKeyword = true;
}

void FunctionOverload::SetDelete(SourcePtr startOfCode)
{
	setCodeDefinitionSource(startOfCode,
		"Cannot set function %s to use the delete keyword because it already "
		"was defined at %s.");
	this->codeSource = startOfCode;
	this->usesDeleteKeyword = true;
}

void FunctionOverload::SetPureVirtual(SourcePtr startOfCode)
{
	setCodeDefinitionSource(startOfCode,
		"Cannot set function %s as pure virtual because it already "
		"was defined at %s.");
	this->codeSource = startOfCode;
	this->isPureVirtual = true;
}

void FunctionOverload::setCodeDefinitionSource(SourcePtr startOfCode,
	                                           const char * const msg)
{
	if (!!codeSource)
	{
		std::string text = str(boost::format(msg)
			% this->getNode()->GetFullName() % codeSource->ToString());
		throw ModelInconsistencyException(startOfCode, text);
	}
	this->codeSource = startOfCode;
}

END_NAMESPACE

#endif
<|endoftext|>


<commit_before>/* -*-  mode: c++; indent-tabs-mode: nil -*- */
//! Simple wrapper that takes a ParameterList and generates all needed meshes.

/*
  ATS is released under the three-clause BSD License.
  The terms of use and "as is" disclaimer for this license are
  provided in the top-level COPYRIGHT file.

  Authors: Ethan Coon (ecoon@lanl.gov)
*/

#include "Epetra_MpiComm.h"
#include "Teuchos_ParameterList.hpp"
#include "Teuchos_TimeMonitor.hpp"

#include "MeshAudit.hh"
#include "MeshFactory.hh"
#include "MeshLogicalFactory.hh"
#include "MeshColumn.hh"
#include "GeometricModel.hh"

#include "ats_mesh_factory.hh"

namespace ATS {

void
createMeshes(Teuchos::ParameterList& mesh_plist,
             const Teuchos::RCP<Epetra_MpiComm>& comm,
             const Teuchos::RCP<Amanzi::AmanziGeometry::GeometricModel>& gm,
             Amanzi::State& S) {
  int num_procs = comm->NumProc();
  int rank = comm->MyPID();

  // create the MSTK factory
  Amanzi::AmanziMesh::MeshFactory factory(comm.get());
  Amanzi::AmanziMesh::FrameworkPreference prefs(factory.preference());
  prefs.clear();
  prefs.push_back(Amanzi::AmanziMesh::MSTK);

  // create the base mesh
  Teuchos::RCP<Amanzi::AmanziMesh::Mesh> mesh;

  if (mesh_plist.isSublist("read mesh file")) {
    // from file
    Teuchos::ParameterList read_params = mesh_plist.sublist("read mesh file");

    // file name
    std::string file;
    if (read_params.isParameter("file")) {
      file = read_params.get<std::string>("file");
    } else {
      Errors::Message msg("\"read mesh file\" list missing \"file\" parameter.");
      Exceptions::amanzi_throw(msg);
    }

    // file format
    std::string format;
    if (read_params.isParameter("format")) {
      // Is the format one that we can read?
      format = read_params.get<std::string>("format");
      if (format != "Exodus II") {
        Errors::Message msg;
        msg << "\"read mesh file\" parameter \"format\" with value \"" << format
            << "\" not understood: valid formats are: \"Exodus II\".";
        Exceptions::amanzi_throw(msg);
      }
    } else {
      Errors::Message msg("\"read mesh file\" parameter \"format\" missing.");
      Exceptions::amanzi_throw(msg);
    }

    // create the mesh from the file
    Teuchos::RCP<Teuchos::Time> volmeshtime = Teuchos::TimeMonitor::getNewCounter("volume mesh creation");
    Teuchos::TimeMonitor timer(*volmeshtime);
    mesh = factory.create(file, gm);

  } else if (mesh_plist.isSublist("generate mesh")) {
    // generated mesh
    Teuchos::ParameterList gen_params = mesh_plist.sublist("generate mesh");
    mesh = factory.create(gen_params, gm);

  } else if (mesh_plist.isSublist("logical mesh")) {
    // -- from logical mesh file
    Amanzi::AmanziMesh::MeshLogicalFactory fac(comm.get(), gm);
    mesh = fac.Create(mesh_plist.sublist("logical mesh"));

  } else if (mesh_plist.isSublist("embedded logical mesh")) {
    Errors::Message msg("\"embedded logical mesh\" option not yet implemented.");
    Exceptions::amanzi_throw(msg);

  } else {
    Errors::Message msg("Must specify mesh sublist of type: \"read mesh file\", \"generate mesh\", or \"logical mesh\".");
    Exceptions::amanzi_throw(msg);
  }

  ASSERT(!mesh.is_null());

  // mesh verification
  bool verify = mesh_plist.get<bool>("verify mesh", false);
  if (verify) {
    if (rank == 0)
      std::cout << "Verifying mesh with Mesh Audit..." << std::endl;
    if (num_procs == 1) {
      Amanzi::MeshAudit mesh_auditor(mesh);
      int status = mesh_auditor.Verify();
      if (status == 0) {
        std::cout << "Mesh Audit confirms that mesh is ok" << std::endl;
      } else {
        Errors::Message msg("Mesh Audit could not verify correctness of mesh.");
        Exceptions::amanzi_throw(msg);
      }
    } else {
      std::ostringstream ofile;
      ofile << "mesh_audit_" << std::setfill('0') << std::setw(4) << rank << ".txt";
      std::ofstream ofs(ofile.str().c_str());
      if (rank == 0)
        std::cout << "Writing Mesh Audit output to " << ofile.str() << ", etc." << std::endl;

      int ierr = 0, aerr = 0;
      Amanzi::MeshAudit mesh_auditor(mesh, ofs);
      int status = mesh_auditor.Verify();        // check the mesh
      if (status != 0) ierr = 1;

      comm->SumAll(&ierr, &aerr, 1);
      if (aerr == 0) {
        if (rank == 0)
          std::cout << "Mesh Audit confirms that mesh is ok" << std::endl;
      } else {
        Errors::Message msg("Mesh Audit could not verify correctness of mesh.");
        Exceptions::amanzi_throw(msg);
      }
    }
  }  // if verify

  // Create the surface mesh if needed
  Teuchos::RCP<Amanzi::AmanziMesh::Mesh> surface_mesh = Teuchos::null;
  Teuchos::RCP<Amanzi::AmanziMesh::Mesh> surface3D_mesh = Teuchos::null;
  if (mesh_plist.isSublist("surface mesh")) {
    Teuchos::ParameterList surface_plist = mesh_plist.sublist("surface mesh");

    std::vector<std::string> setnames;
    if (surface_plist.isParameter("surface sideset name")) {
      setnames.push_back(surface_plist.get<std::string>("surface sideset name"));
    } else if (surface_plist.isParameter("surface sideset names")) {
      setnames = surface_plist.get<Teuchos::Array<std::string> >("surface sideset names").toVector();
    } else {
      Errors::Message message("Surface mesh sublist missing parameter \"surface sideset names\".");
      Exceptions::amanzi_throw(message);
    }

    if (mesh->manifold_dimension() == 3) {
      surface3D_mesh = factory.create(&*mesh,setnames,Amanzi::AmanziMesh::FACE,false,false);
      surface_mesh = factory.create(&*mesh,setnames,Amanzi::AmanziMesh::FACE,true,false);
    } else {
      surface3D_mesh = mesh;
      surface_mesh = factory.create(&*mesh,setnames,Amanzi::AmanziMesh::CELL,true,false);
    }

    bool surf_verify = surface_plist.get<bool>("verify mesh", false);
    if (surf_verify) {
      if (rank == 0)
        std::cout << "Verifying surface mesh with Mesh Audit..." << std::endl;
      if (num_procs == 1) {
        Amanzi::MeshAudit surf_mesh_auditor(surface_mesh);
        int status = surf_mesh_auditor.Verify();
        if (status == 0) {
          std::cout << "Mesh Audit confirms that surface mesh is ok" << std::endl;
        } else {
          Errors::Message msg("Mesh Audit could not verify correctness of surface mesh.");
          Exceptions::amanzi_throw(msg);
        }
      } else {
        std::ostringstream ofile;
        ofile << "surf_mesh_audit_" << std::setfill('0') << std::setw(4) << rank << ".txt";
        std::ofstream ofs(ofile.str().c_str());
        if (rank == 0)
          std::cout << "Writing Surface Mesh Audit output to " << ofile.str() << ", etc." << std::endl;

        int ierr = 0, aerr = 0;
        Amanzi::MeshAudit surf_mesh_auditor(mesh, ofs);
        int status = surf_mesh_auditor.Verify();        // check the mesh
        if (status != 0) ierr = 1;

        comm->SumAll(&ierr, &aerr, 1);
        if (aerr == 0 && rank == 0) {
          std::cout << "Mesh Audit confirms that surface mesh is ok" << std::endl;
        } else {
          Errors::Message msg("Mesh Audit could not verify correctness of surface mesh.");
          Exceptions::amanzi_throw(msg);
        }
      }
    }  // if surf_verify

    if (surface_plist.isParameter("export mesh to file")) {
      std::string export_surf_mesh_filename =
            surface_plist.get<std::string>("export mesh to file");
      surface3D_mesh->write_to_exodus_file(export_surf_mesh_filename);
    }
  }

  // column meshes
  std::vector<Teuchos::RCP<Amanzi::AmanziMesh::Mesh> > col_meshes;
  if (mesh_plist.isSublist("column meshes")) {
    int nc = mesh->num_columns();
    col_meshes.resize(nc, Teuchos::null);
    for (int c=0; c!=nc; ++c) {
      col_meshes[c] = Teuchos::rcp(new Amanzi::AmanziMesh::MeshColumn(*mesh, c));
    }
  }

  Teuchos::TimeMonitor::summarize();
  Teuchos::TimeMonitor::zeroOutTimers();

  // register meshes with state
  bool deformable = mesh_plist.get<bool>("deformable mesh",false);
  S.RegisterDomainMesh(mesh, deformable);
  if (surface3D_mesh != Teuchos::null)
    S.RegisterMesh("surface_3d", surface3D_mesh, deformable);
  if (surface_mesh != Teuchos::null)
    S.RegisterMesh("surface", surface_mesh, deformable);

  if (col_meshes.size() > 0) {
    for (int c=0; c!=col_meshes.size(); ++c) {
      std::stringstream namestream;
      namestream << "column_" << c;
      S.RegisterMesh(namestream.str(), col_meshes[c], deformable);
    }
  }
}

} // namespace ATS
<commit_msg>adds input spec method for alias surface as the main computational domain, gets around forcing the flow pk to do this and enables cases where there is no flow pk<commit_after>/* -*-  mode: c++; indent-tabs-mode: nil -*- */
//! Simple wrapper that takes a ParameterList and generates all needed meshes.

/*
  ATS is released under the three-clause BSD License.
  The terms of use and "as is" disclaimer for this license are
  provided in the top-level COPYRIGHT file.

  Authors: Ethan Coon (ecoon@lanl.gov)
*/

#include "Epetra_MpiComm.h"
#include "Teuchos_ParameterList.hpp"
#include "Teuchos_TimeMonitor.hpp"

#include "MeshAudit.hh"
#include "MeshFactory.hh"
#include "MeshLogicalFactory.hh"
#include "MeshColumn.hh"
#include "GeometricModel.hh"

#include "ats_mesh_factory.hh"

namespace ATS {

void
createMeshes(Teuchos::ParameterList& mesh_plist,
             const Teuchos::RCP<Epetra_MpiComm>& comm,
             const Teuchos::RCP<Amanzi::AmanziGeometry::GeometricModel>& gm,
             Amanzi::State& S) {
  int num_procs = comm->NumProc();
  int rank = comm->MyPID();

  // create the MSTK factory
  Amanzi::AmanziMesh::MeshFactory factory(comm.get());
  Amanzi::AmanziMesh::FrameworkPreference prefs(factory.preference());
  prefs.clear();
  prefs.push_back(Amanzi::AmanziMesh::MSTK);

  // create the base mesh
  Teuchos::RCP<Amanzi::AmanziMesh::Mesh> mesh;

  if (mesh_plist.isSublist("read mesh file")) {
    // from file
    Teuchos::ParameterList read_params = mesh_plist.sublist("read mesh file");

    // file name
    std::string file;
    if (read_params.isParameter("file")) {
      file = read_params.get<std::string>("file");
    } else {
      Errors::Message msg("\"read mesh file\" list missing \"file\" parameter.");
      Exceptions::amanzi_throw(msg);
    }

    // file format
    std::string format;
    if (read_params.isParameter("format")) {
      // Is the format one that we can read?
      format = read_params.get<std::string>("format");
      if (format != "Exodus II") {
        Errors::Message msg;
        msg << "\"read mesh file\" parameter \"format\" with value \"" << format
            << "\" not understood: valid formats are: \"Exodus II\".";
        Exceptions::amanzi_throw(msg);
      }
    } else {
      Errors::Message msg("\"read mesh file\" parameter \"format\" missing.");
      Exceptions::amanzi_throw(msg);
    }

    // create the mesh from the file
    Teuchos::RCP<Teuchos::Time> volmeshtime = Teuchos::TimeMonitor::getNewCounter("volume mesh creation");
    Teuchos::TimeMonitor timer(*volmeshtime);
    mesh = factory.create(file, gm);

  } else if (mesh_plist.isSublist("generate mesh")) {
    // generated mesh
    Teuchos::ParameterList gen_params = mesh_plist.sublist("generate mesh");
    mesh = factory.create(gen_params, gm);

  } else if (mesh_plist.isSublist("logical mesh")) {
    // -- from logical mesh file
    Amanzi::AmanziMesh::MeshLogicalFactory fac(comm.get(), gm);
    mesh = fac.Create(mesh_plist.sublist("logical mesh"));

  } else if (mesh_plist.isSublist("embedded logical mesh")) {
    Errors::Message msg("\"embedded logical mesh\" option not yet implemented.");
    Exceptions::amanzi_throw(msg);

  } else {
    Errors::Message msg("Must specify mesh sublist of type: \"read mesh file\", \"generate mesh\", or \"logical mesh\".");
    Exceptions::amanzi_throw(msg);
  }

  ASSERT(!mesh.is_null());

  // mesh verification
  bool verify = mesh_plist.get<bool>("verify mesh", false);
  if (verify) {
    if (rank == 0)
      std::cout << "Verifying mesh with Mesh Audit..." << std::endl;
    if (num_procs == 1) {
      Amanzi::MeshAudit mesh_auditor(mesh);
      int status = mesh_auditor.Verify();
      if (status == 0) {
        std::cout << "Mesh Audit confirms that mesh is ok" << std::endl;
      } else {
        Errors::Message msg("Mesh Audit could not verify correctness of mesh.");
        Exceptions::amanzi_throw(msg);
      }
    } else {
      std::ostringstream ofile;
      ofile << "mesh_audit_" << std::setfill('0') << std::setw(4) << rank << ".txt";
      std::ofstream ofs(ofile.str().c_str());
      if (rank == 0)
        std::cout << "Writing Mesh Audit output to " << ofile.str() << ", etc." << std::endl;

      int ierr = 0, aerr = 0;
      Amanzi::MeshAudit mesh_auditor(mesh, ofs);
      int status = mesh_auditor.Verify();        // check the mesh
      if (status != 0) ierr = 1;

      comm->SumAll(&ierr, &aerr, 1);
      if (aerr == 0) {
        if (rank == 0)
          std::cout << "Mesh Audit confirms that mesh is ok" << std::endl;
      } else {
        Errors::Message msg("Mesh Audit could not verify correctness of mesh.");
        Exceptions::amanzi_throw(msg);
      }
    }
  }  // if verify

  // Create the surface mesh if needed
  Teuchos::RCP<Amanzi::AmanziMesh::Mesh> surface_mesh = Teuchos::null;
  Teuchos::RCP<Amanzi::AmanziMesh::Mesh> surface3D_mesh = Teuchos::null;
  if (mesh_plist.isSublist("surface mesh")) {
    Teuchos::ParameterList surface_plist = mesh_plist.sublist("surface mesh");
    if (surface_plist.get<bool>("aliased", false)) {
      surface_mesh = mesh;

    } else {
      std::vector<std::string> setnames;
      if (surface_plist.isParameter("surface sideset name")) {
        setnames.push_back(surface_plist.get<std::string>("surface sideset name"));
      } else if (surface_plist.isParameter("surface sideset names")) {
        setnames = surface_plist.get<Teuchos::Array<std::string> >("surface sideset names").toVector();
      } else {
        Errors::Message message("Surface mesh sublist missing parameter \"surface sideset names\".");
        Exceptions::amanzi_throw(message);
      }

      if (mesh->manifold_dimension() == 3) {
        surface3D_mesh = factory.create(&*mesh,setnames,Amanzi::AmanziMesh::FACE,false,false);
        surface_mesh = factory.create(&*mesh,setnames,Amanzi::AmanziMesh::FACE,true,false);
      } else {
        surface3D_mesh = mesh;
        surface_mesh = factory.create(&*mesh,setnames,Amanzi::AmanziMesh::CELL,true,false);
      }

      bool surf_verify = surface_plist.get<bool>("verify mesh", false);
      if (surf_verify) {
        if (rank == 0)
          std::cout << "Verifying surface mesh with Mesh Audit..." << std::endl;
        if (num_procs == 1) {
          Amanzi::MeshAudit surf_mesh_auditor(surface_mesh);
          int status = surf_mesh_auditor.Verify();
          if (status == 0) {
            std::cout << "Mesh Audit confirms that surface mesh is ok" << std::endl;
          } else {
            Errors::Message msg("Mesh Audit could not verify correctness of surface mesh.");
            Exceptions::amanzi_throw(msg);
          }
        } else {
          std::ostringstream ofile;
          ofile << "surf_mesh_audit_" << std::setfill('0') << std::setw(4) << rank << ".txt";
          std::ofstream ofs(ofile.str().c_str());
          if (rank == 0)
            std::cout << "Writing Surface Mesh Audit output to " << ofile.str() << ", etc." << std::endl;

          int ierr = 0, aerr = 0;
          Amanzi::MeshAudit surf_mesh_auditor(mesh, ofs);
          int status = surf_mesh_auditor.Verify();        // check the mesh
          if (status != 0) ierr = 1;

          comm->SumAll(&ierr, &aerr, 1);
          if (aerr == 0 && rank == 0) {
            std::cout << "Mesh Audit confirms that surface mesh is ok" << std::endl;
          } else {
            Errors::Message msg("Mesh Audit could not verify correctness of surface mesh.");
            Exceptions::amanzi_throw(msg);
          }
        }
      }  // if surf_verify

      if (surface_plist.isParameter("export mesh to file")) {
        std::string export_surf_mesh_filename =
            surface_plist.get<std::string>("export mesh to file");
        surface3D_mesh->write_to_exodus_file(export_surf_mesh_filename);
      }
    }
  }

  // column meshes
  std::vector<Teuchos::RCP<Amanzi::AmanziMesh::Mesh> > col_meshes;
  if (mesh_plist.isSublist("column meshes")) {
    int nc = mesh->num_columns();
    col_meshes.resize(nc, Teuchos::null);
    for (int c=0; c!=nc; ++c) {
      col_meshes[c] = Teuchos::rcp(new Amanzi::AmanziMesh::MeshColumn(*mesh, c));
    }
  }

  Teuchos::TimeMonitor::summarize();
  Teuchos::TimeMonitor::zeroOutTimers();

  // register meshes with state
  bool deformable = mesh_plist.get<bool>("deformable mesh",false);
  S.RegisterDomainMesh(mesh, deformable);
  if (surface3D_mesh != Teuchos::null)
    S.RegisterMesh("surface_3d", surface3D_mesh, deformable);
  if (surface_mesh != Teuchos::null)
    S.RegisterMesh("surface", surface_mesh, deformable);

  if (col_meshes.size() > 0) {
    for (int c=0; c!=col_meshes.size(); ++c) {
      std::stringstream namestream;
      namestream << "column_" << c;
      S.RegisterMesh(namestream.str(), col_meshes[c], deformable);
    }
  }
}

} // namespace ATS
<|endoftext|>