<commit_before>#include <Xdmf.h>
#include <XdmfSet.h>

#include <sstream>
#include <map>
#include <stack>
#include <vector>

#include "XdmfFortran.h"

// This works with g77. Different compilers require different
// name mangling.
#define XdmfInit xdmfinit_
#define XdmfSetTime xdmfsettime_
#define XdmfAddCollection xdmfaddcollection_
#define XdmfCloseCollection xdmfclosecollection_
#define XdmfSetGridTopology xdmfsetgridtopology_
#define XdmfSetGridGeometry xdmfsetgridgeometry_
#define XdmfAddGridAttribute xdmfaddgridattribute_
#define XdmfAddArray xdmfaddarray_
#define XdmfWriteGrid xdmfwritegrid_
#define XdmfWriteToFile xdmfwritetofile_
#define XdmfSerialize xdmfserialize_
#define XdmfGetDOM xdmfgetdom_

XdmfFortran::XdmfFortran()
{
	myDOM = new XdmfDOM();
	myRoot = new XdmfRoot();
	myDomain = new XdmfDomain();
	currentTime = -1;
	inCollection = false;
}

XdmfFortran::~XdmfFortran()
{

}

//
// C++ will mangle the name based on the argument list. This tells the
// compiler not to mangle the name so we can call it from 'C' (but
// really Fortran in this case)
//
extern "C" {

	/**
	 *
	 * Initialize a new Xdmf file.
	 *
	 */
	long XdmfInit(char *outputName)
	{
		XdmfFortran * myPointer = new(XdmfFortran);
		myPointer->myRoot->SetDOM(myPointer->myDOM);
		myPointer->myRoot->Build();
		myPointer->myRoot->Insert(myPointer->myDomain);
		myPointer->myName = outputName;
		return (long)myPointer;
	}

	/**
	 *
	 * Helper function to write different datatypes to an XdmfArray.
	 *
	 */
	void WriteToXdmfArray(XdmfArray * array, XdmfPointer * data)
	{
		switch(array->GetNumberType()){
		case XDMF_INT8_TYPE :
			array->SetValues(0, (XdmfInt8*)data, array->GetNumberOfElements());
			return;
		case XDMF_INT16_TYPE :
			array->SetValues(0, (XdmfInt16*)data, array->GetNumberOfElements());
			return;
		case XDMF_INT32_TYPE :
			array->SetValues(0, (XdmfInt32*)data, array->GetNumberOfElements());
			return;
		case XDMF_INT64_TYPE :
			array->SetValues(0, (XdmfInt64*)data, array->GetNumberOfElements());
			return;
		case XDMF_FLOAT32_TYPE :
			array->SetValues(0, (XdmfFloat32*)data, array->GetNumberOfElements());
			return;
		case XDMF_FLOAT64_TYPE :
			array->SetValues(0, (XdmfFloat64*)data, array->GetNumberOfElements());
			return;
		case XDMF_UINT8_TYPE :
			array->SetValues(0, (XdmfUInt8*)data, array->GetNumberOfElements());
			return;
		case XDMF_UINT16_TYPE :
			array->SetValues(0, (XdmfUInt16*)data, array->GetNumberOfElements());
			return;
		case XDMF_UINT32_TYPE :
			array->SetValues(0, (XdmfUInt32*)data, array->GetNumberOfElements());
			return;
		default:
			array->SetValues(0, (XdmfFloat64*)data, array->GetNumberOfElements());
			return;
		}
	}

	/**
	 *
	 * Set a time to be assigned to the next grid.
	 *
	 */
	void XdmfSetTime(long * pointer, double * t)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		myPointer->currentTime = *t;
	}

	/**
	 *
	 * Add a collection to the XdmfDOM.  Collections can be 'Spatial' or 'Temporal' type.
	 * Nested collections are supported.
	 *
	 */
	void XdmfAddCollection(long * pointer, char * collectionType)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		XdmfGrid * currentCollection = new XdmfGrid();
		currentCollection->SetGridType(XDMF_GRID_COLLECTION);
		currentCollection->SetCollectionTypeFromString(collectionType);
		if (myPointer->inCollection)
		{
			myPointer->myCollections.top()->Insert(currentCollection);
		}
		else
		{
			myPointer->myDomain->Insert(currentCollection);
		}
		currentCollection->Build();
		myPointer->myCollections.push(currentCollection);
		myPointer->inCollection = true;
	}

	/**
	 *
	 * Close the current open collection.  If within a nested collection, close
	 * the most deeply nested collection.
	 *
	 */
	void XdmfCloseCollection(long * pointer)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		if(myPointer->inCollection)
		{
			myPointer->inCollection = false;
			myPointer->myCollections.pop();
		}
	}

	/**
	 *
	 * Set the topology type to be assigned to the next grid.
	 * Only XDMF_INT_32 type currently supported for Topology --> INTEGER*4
	 *
	 */
	void XdmfSetGridTopology(long * pointer, char * topologyType, int * numberOfElements, XdmfInt32 * conns)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		myPointer->myTopology = new XdmfTopology();
		myPointer->myTopology->SetTopologyTypeFromString(topologyType);
		myPointer->myTopology->SetNumberOfElements(*numberOfElements);

		// Fortran is 1 based while c++ is 0 based so
		// Either subtract 1 from all connections or specify a BaseOffset
		//myPointer->myTopology->SetBaseOffset(1);

		// If you haven't assigned an XdmfArray, GetConnectivity() will create one.
		XdmfArray * myConnections = myPointer->myTopology->GetConnectivity();
		myConnections->SetNumberOfElements(*numberOfElements * myPointer->myTopology->GetNodesPerElement());
		myConnections->SetNumberType(XDMF_INT32_TYPE);
		myConnections->SetValues(0, conns, *numberOfElements * myPointer->myTopology->GetNodesPerElement());
	}

	/**
	 *
	 * Set the geometry type to be assigned to the next grid.
	 *
	 */
	void XdmfSetGridGeometry(long * pointer, char * geometryType, char * numberType, int * numberOfPoints, XdmfPointer * points)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		myPointer->myGeometry = new XdmfGeometry();
		myPointer->myGeometry->SetGeometryTypeFromString(geometryType);
		myPointer->myGeometry->SetNumberOfPoints(*numberOfPoints);

		XdmfArray * myPoints = myPointer->myGeometry->GetPoints();
		myPoints->SetNumberTypeFromString(numberType);

		switch(myPointer->myGeometry->GetGeometryType())
		{
			case XDMF_GEOMETRY_XYZ :
				myPoints->SetNumberOfElements(*numberOfPoints * 3);
				break;
			case XDMF_GEOMETRY_X_Y_Z :
				myPoints->SetNumberOfElements(*numberOfPoints * 3);
				break;
			case XDMF_GEOMETRY_XY :
				myPoints->SetNumberOfElements(*numberOfPoints * 2);
				break;
			case XDMF_GEOMETRY_X_Y :
				myPoints->SetNumberOfElements(*numberOfPoints * 2);
				break;
			case XDMF_GEOMETRY_VXVYVZ :
				//TODO: FIX THIS
				myPoints->SetNumberOfElements(*numberOfPoints * 3);
				break;
			case XDMF_GEOMETRY_ORIGIN_DXDYDZ :
				myPoints->SetNumberOfElements(6);
				break;
			default:
				myPoints->SetNumberOfElements(*numberOfPoints * 3);
				break;
		}
		WriteToXdmfArray(myPoints, points);
	}

	/**
	 *
	 * Add an attribute to be written to the next grid.  Multiple attributes can
	 * be added and written to a single grid.
	 *
	 */
	void XdmfAddGridAttribute(long * pointer, char * attributeName, char * numberType, char * attributeCenter, char * attributeType, int * numberOfPoints, XdmfPointer * data)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		XdmfAttribute * currAttribute = new XdmfAttribute();
		currAttribute->SetName(attributeName);
		currAttribute->SetAttributeCenterFromString(attributeCenter);
		currAttribute->SetAttributeTypeFromString(attributeType);

		XdmfArray * array = currAttribute->GetValues();
		array->SetNumberTypeFromString(numberType);
		array->SetNumberOfElements(*numberOfPoints);
		WriteToXdmfArray(array, data);
		myPointer->myAttributes.push_back(currAttribute);
	}

	/**
	 *
	 * Add an array to the XdmfDOM.  Arrays can be written within collections or
	 * within the top level domain.
	 *
	 */
	void XdmfAddArray(long * pointer, char * name, char * numberType, int * numberOfValues, XdmfPointer * data)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;

		XdmfSet * currSet = new XdmfSet();
    	currSet->SetDOM(myPointer->myDOM);
       	currSet->SetSetType(XDMF_SET_TYPE_NODE);
       	currSet->SetName(name);

       	// Copy Elements from Set to XdmfArray
       	XdmfArray * array = currSet->GetIds();
       	array->SetNumberTypeFromString(numberType);
		array->SetNumberOfElements(*numberOfValues);
		std::stringstream heavyDataName;
		heavyDataName << myPointer->myName << ".h5:/" <<  name;;
		array->SetHeavyDataSetName(heavyDataName.str().c_str());
		WriteToXdmfArray(array, data);

		if (myPointer->inCollection)
		{
			myPointer->myCollections.top()->Insert(currSet);
		}
		else
		{
			XdmfGrid * myGrid = new XdmfGrid();
			myGrid->SetDOM(myPointer->myDOM);
	        myGrid->SetElement(myPointer->myDOM->FindElement("Domain"));
	        myGrid->Insert(currSet);
		}

        currSet->Build();
	}

	/**
	 *
	 * Add a grid to the XdmfDOM.  Assign the current topology, geometry, and grid attributes
	 * to grid.  If within a collection, add grid to the collection, otherwise
	 * add to the top level domain.  Assign time value if value is nonnegative.
	 *
	 */
	void XdmfWriteGrid(long * pointer, char * gridName)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		XdmfGrid * grid = new XdmfGrid();

		std::stringstream totalGridName;
		if(myPointer->myWrittenGrids.find(gridName) == myPointer->myWrittenGrids.end())
		{
			myPointer->myWrittenGrids[gridName] = 1;
			totalGridName << gridName;
		}
		else
		{
			myPointer->myWrittenGrids[gridName]++;
			totalGridName << gridName << "_" << myPointer->myWrittenGrids[gridName];
		}

		grid->SetName(totalGridName.str().c_str());

		//Modify HDF5 names so we aren't writing over top of our data!
		std::stringstream topologyDataName;
		topologyDataName << myPointer->myName << ".h5:/" <<  totalGridName.str() << "/Connections";
		myPointer->myTopology->GetConnectivity()->SetHeavyDataSetName(topologyDataName.str().c_str());
		grid->SetTopology(myPointer->myTopology);

		std::stringstream geometryDataName;
		geometryDataName << myPointer->myName << ".h5:/" <<  totalGridName.str() << "/XYZ";
		myPointer->myGeometry->GetPoints()->SetHeavyDataSetName(geometryDataName.str().c_str());
		grid->SetGeometry(myPointer->myGeometry);

		if (myPointer->inCollection)
		{
			myPointer->myCollections.top()->Insert(grid);
		}
		else
		{
			myPointer->myDomain->Insert(grid);
		}

		XdmfTime * t = new XdmfTime();
		if (myPointer->currentTime >= 0)
		{
			t->SetTimeType(XDMF_TIME_SINGLE);
			t->SetValue(myPointer->currentTime);
			grid->Insert(t);
			myPointer->currentTime = -1;
		}

		while(myPointer->myAttributes.size() > 0)
		{
			XdmfAttribute * currAttribute = myPointer->myAttributes.back();

			std::stringstream attributeDataName;
			attributeDataName << myPointer->myName << ".h5:/" <<  totalGridName.str() << "/" << currAttribute->GetName();
			currAttribute->GetValues()->SetHeavyDataSetName(attributeDataName.str().c_str());

			grid->Insert(currAttribute);
			myPointer->myAttributes.pop_back();
		}

		grid->Build();
	}

	/**
	 *
	 * Write constructed Xdmf file to disk with filename created upon initialization
	 *
	 */
	void XdmfWriteToFile(long * pointer)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		std::stringstream dataName;
		dataName << myPointer->myName << ".xmf";
		myPointer->myDOM->Write(dataName.str().c_str());
	}

	/**
	 *
	 * Print current XdmfDOM to console
	 *
	 */
	void XdmfSerialize(long * pointer)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		cout << myPointer->myDOM->Serialize() << endl;
	}

	/**
	 *
	 * Copy current XdmfDOM to memory pointed to by charPointer
	 *
	 */
	void XdmfGetDOM(long * pointer, char * charPointer)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		strcpy(charPointer, myPointer->myDOM->Serialize());
	}
}
<commit_msg>BUG: Clean up memory and add Close() function<commit_after>/*******************************************************************/
/*                               XDMF                              */
/*                   eXtensible Data Model and Format              */
/*                                                                 */
/*  Id : Id  */
/*  Date : $Date$ */
/*  Version : $Revision$ */
/*                                                                 */
/*  Author:                                                        */
/*     Kenneth Leiter                                              */
/*     kenneth.leiter@arl.army.mil                                 */
/*     US Army Research Laboratory                                 */
/*     Aberdeen Proving Ground, MD                                 */
/*                                                                 */
/*     Copyright @ 2009 US Army Research Laboratory                */
/*     All Rights Reserved                                         */
/*     See Copyright.txt or http://www.arl.hpc.mil/ice for details */
/*                                                                 */
/*     This software is distributed WITHOUT ANY WARRANTY; without  */
/*     even the implied warranty of MERCHANTABILITY or FITNESS     */
/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice   */
/*     for more information.                                       */
/*                                                                 */
/*******************************************************************/

#include <Xdmf.h>
#include <XdmfSet.h>

#include <sstream>
#include <map>
#include <stack>
#include <vector>

#include "XdmfFortran.h"

// This works with g77. Different compilers require different
// name mangling.
#define XdmfInit xdmfinit_
#define XdmfSetTime xdmfsettime_
#define XdmfAddCollection xdmfaddcollection_
#define XdmfCloseCollection xdmfclosecollection_
#define XdmfSetGridTopology xdmfsetgridtopology_
#define XdmfSetGridGeometry xdmfsetgridgeometry_
#define XdmfAddGridAttribute xdmfaddgridattribute_
#define XdmfAddArray xdmfaddarray_
#define XdmfWriteGrid xdmfwritegrid_
#define XdmfWriteToFile xdmfwritetofile_
#define XdmfSerialize xdmfserialize_
#define XdmfGetDOM xdmfgetdom_
#define XdmfClose xdmfclose_

XdmfFortran::XdmfFortran()
{
	myDOM = new XdmfDOM();
	myRoot = new XdmfRoot();
	myDomain = new XdmfDomain();
	currentTime = -1;
	inCollection = false;
}

XdmfFortran::~XdmfFortran()
{
	delete myDOM;
	delete myRoot;
	delete myDomain;
	while(!myCollections.empty())
	{
		delete myCollections.top();
		myCollections.pop();
	}

	while(!myAttributes.empty())
	{
		delete myAttributes.back();
		myAttributes.pop_back();
	}
}

//
// C++ will mangle the name based on the argument list. This tells the
// compiler not to mangle the name so we can call it from 'C' (but
// really Fortran in this case)
//
extern "C" {

	/**
	 *
	 * Initialize a new Xdmf file.
	 *
	 */
	long XdmfInit(char *outputName)
	{
		XdmfFortran * myPointer = new XdmfFortran();
		myPointer->myRoot->SetDOM(myPointer->myDOM);
		myPointer->myRoot->Build();
		myPointer->myRoot->Insert(myPointer->myDomain);
		myPointer->myName = outputName;
		return (long)myPointer;
	}

	/**
	 *
	 * Helper function to write different datatypes to an XdmfArray.
	 *
	 */
	void WriteToXdmfArray(XdmfArray * array, XdmfPointer * data)
	{
		switch(array->GetNumberType()){
		case XDMF_INT8_TYPE :
			array->SetValues(0, (XdmfInt8*)data, array->GetNumberOfElements());
			return;
		case XDMF_INT16_TYPE :
			array->SetValues(0, (XdmfInt16*)data, array->GetNumberOfElements());
			return;
		case XDMF_INT32_TYPE :
			array->SetValues(0, (XdmfInt32*)data, array->GetNumberOfElements());
			return;
		case XDMF_INT64_TYPE :
			array->SetValues(0, (XdmfInt64*)data, array->GetNumberOfElements());
			return;
		case XDMF_FLOAT32_TYPE :
			array->SetValues(0, (XdmfFloat32*)data, array->GetNumberOfElements());
			return;
		case XDMF_FLOAT64_TYPE :
			array->SetValues(0, (XdmfFloat64*)data, array->GetNumberOfElements());
			return;
		case XDMF_UINT8_TYPE :
			array->SetValues(0, (XdmfUInt8*)data, array->GetNumberOfElements());
			return;
		case XDMF_UINT16_TYPE :
			array->SetValues(0, (XdmfUInt16*)data, array->GetNumberOfElements());
			return;
		case XDMF_UINT32_TYPE :
			array->SetValues(0, (XdmfUInt32*)data, array->GetNumberOfElements());
			return;
		default:
			array->SetValues(0, (XdmfFloat64*)data, array->GetNumberOfElements());
			return;
		}
	}

	/**
	 *
	 * Set a time to be assigned to the next grid.
	 *
	 */
	void XdmfSetTime(long * pointer, double * t)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		myPointer->currentTime = *t;
	}

	/**
	 *
	 * Add a collection to the XdmfDOM.  Collections can be 'Spatial' or 'Temporal' type.
	 * Nested collections are supported.
	 *
	 */
	void XdmfAddCollection(long * pointer, char * collectionType)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		XdmfGrid * currentCollection = new XdmfGrid();
		currentCollection->SetGridType(XDMF_GRID_COLLECTION);
		currentCollection->SetCollectionTypeFromString(collectionType);
		if (myPointer->inCollection)
		{
			myPointer->myCollections.top()->Insert(currentCollection);
		}
		else
		{
			myPointer->myDomain->Insert(currentCollection);
		}
		currentCollection->Build();
		myPointer->myCollections.push(currentCollection);
		myPointer->inCollection = true;
	}

	/**
	 *
	 * Close the current open collection.  If within a nested collection, close
	 * the most deeply nested collection.
	 *
	 */
	void XdmfCloseCollection(long * pointer)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		if(myPointer->inCollection)
		{
			myPointer->inCollection = false;
			myPointer->myCollections.pop();
		}
	}

	/**
	 *
	 * Set the topology type to be assigned to the next grid.
	 * Only XDMF_INT_32 type currently supported for Topology --> INTEGER*4
	 *
	 */
	void XdmfSetGridTopology(long * pointer, char * topologyType, int * numberOfElements, XdmfInt32 * conns)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		myPointer->myTopology = new XdmfTopology();
		myPointer->myTopology->SetTopologyTypeFromString(topologyType);
		myPointer->myTopology->SetNumberOfElements(*numberOfElements);

		// Fortran is 1 based while c++ is 0 based so
		// Either subtract 1 from all connections or specify a BaseOffset
		//myPointer->myTopology->SetBaseOffset(1);

		// If you haven't assigned an XdmfArray, GetConnectivity() will create one.
		XdmfArray * myConnections = myPointer->myTopology->GetConnectivity();
		myConnections->SetNumberOfElements(*numberOfElements * myPointer->myTopology->GetNodesPerElement());
		myConnections->SetNumberType(XDMF_INT32_TYPE);
		myConnections->SetValues(0, conns, *numberOfElements * myPointer->myTopology->GetNodesPerElement());
	}

	/**
	 *
	 * Set the geometry type to be assigned to the next grid.
	 *
	 */
	void XdmfSetGridGeometry(long * pointer, char * geometryType, char * numberType, int * numberOfPoints, XdmfPointer * points)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		myPointer->myGeometry = new XdmfGeometry();
		myPointer->myGeometry->SetGeometryTypeFromString(geometryType);
		myPointer->myGeometry->SetNumberOfPoints(*numberOfPoints);

		XdmfArray * myPoints = myPointer->myGeometry->GetPoints();
		myPoints->SetNumberTypeFromString(numberType);

		switch(myPointer->myGeometry->GetGeometryType())
		{
			case XDMF_GEOMETRY_XYZ :
				myPoints->SetNumberOfElements(*numberOfPoints * 3);
				break;
			case XDMF_GEOMETRY_X_Y_Z :
				myPoints->SetNumberOfElements(*numberOfPoints * 3);
				break;
			case XDMF_GEOMETRY_XY :
				myPoints->SetNumberOfElements(*numberOfPoints * 2);
				break;
			case XDMF_GEOMETRY_X_Y :
				myPoints->SetNumberOfElements(*numberOfPoints * 2);
				break;
			case XDMF_GEOMETRY_VXVYVZ :
				//TODO: FIX THIS
				myPoints->SetNumberOfElements(*numberOfPoints * 3);
				break;
			case XDMF_GEOMETRY_ORIGIN_DXDYDZ :
				myPoints->SetNumberOfElements(6);
				break;
			default:
				myPoints->SetNumberOfElements(*numberOfPoints * 3);
				break;
		}
		WriteToXdmfArray(myPoints, points);
	}

	/**
	 *
	 * Add an attribute to be written to the next grid.  Multiple attributes can
	 * be added and written to a single grid.
	 *
	 */
	void XdmfAddGridAttribute(long * pointer, char * attributeName, char * numberType, char * attributeCenter, char * attributeType, int * numberOfPoints, XdmfPointer * data)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		XdmfAttribute * currAttribute = new XdmfAttribute();
		currAttribute->SetName(attributeName);
		currAttribute->SetAttributeCenterFromString(attributeCenter);
		currAttribute->SetAttributeTypeFromString(attributeType);

		XdmfArray * array = currAttribute->GetValues();
		array->SetNumberTypeFromString(numberType);
		array->SetNumberOfElements(*numberOfPoints);
		WriteToXdmfArray(array, data);
		myPointer->myAttributes.push_back(currAttribute);
	}

	/**
	 *
	 * Add an array to the XdmfDOM.  Arrays can be written within collections or
	 * within the top level domain.
	 *
	 */
	void XdmfAddArray(long * pointer, char * name, char * numberType, int * numberOfValues, XdmfPointer * data)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;

		XdmfSet * currSet = new XdmfSet();
    	currSet->SetDOM(myPointer->myDOM);
       	currSet->SetSetType(XDMF_SET_TYPE_NODE);
       	currSet->SetName(name);

       	// Copy Elements from Set to XdmfArray
       	XdmfArray * array = currSet->GetIds();
       	array->SetNumberTypeFromString(numberType);
		array->SetNumberOfElements(*numberOfValues);
		std::stringstream heavyDataName;
		heavyDataName << myPointer->myName << ".h5:/" <<  name;;
		array->SetHeavyDataSetName(heavyDataName.str().c_str());
		WriteToXdmfArray(array, data);

		if (myPointer->inCollection)
		{
			myPointer->myCollections.top()->Insert(currSet);
		}
		else
		{
			XdmfGrid * myGrid = new XdmfGrid();
			myGrid->SetDOM(myPointer->myDOM);
	        myGrid->SetElement(myPointer->myDOM->FindElement("Domain"));
	        myGrid->Insert(currSet);
		}

        currSet->Build();
	}

	/**
	 *
	 * Add a grid to the XdmfDOM.  Assign the current topology, geometry, and grid attributes
	 * to grid.  If within a collection, add grid to the collection, otherwise
	 * add to the top level domain.  Assign time value if value is nonnegative.
	 *
	 */
	void XdmfWriteGrid(long * pointer, char * gridName)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		XdmfGrid * grid = new XdmfGrid();

		std::stringstream totalGridName;
		if(myPointer->myWrittenGrids.find(gridName) == myPointer->myWrittenGrids.end())
		{
			myPointer->myWrittenGrids[gridName] = 1;
			totalGridName << gridName;
		}
		else
		{
			myPointer->myWrittenGrids[gridName]++;
			totalGridName << gridName << "_" << myPointer->myWrittenGrids[gridName];
		}

		grid->SetName(totalGridName.str().c_str());

		//Modify HDF5 names so we aren't writing over top of our data!
		std::stringstream topologyDataName;
		topologyDataName << myPointer->myName << ".h5:/" <<  totalGridName.str() << "/Connections";
		myPointer->myTopology->GetConnectivity()->SetHeavyDataSetName(topologyDataName.str().c_str());
		grid->SetTopology(myPointer->myTopology);

		std::stringstream geometryDataName;
		geometryDataName << myPointer->myName << ".h5:/" <<  totalGridName.str() << "/XYZ";
		myPointer->myGeometry->GetPoints()->SetHeavyDataSetName(geometryDataName.str().c_str());
		grid->SetGeometry(myPointer->myGeometry);

		if (myPointer->inCollection)
		{
			myPointer->myCollections.top()->Insert(grid);
		}
		else
		{
			myPointer->myDomain->Insert(grid);
		}

		XdmfTime * t = new XdmfTime();
		if (myPointer->currentTime >= 0)
		{
			t->SetTimeType(XDMF_TIME_SINGLE);
			t->SetValue(myPointer->currentTime);
			grid->Insert(t);
			myPointer->currentTime = -1;
		}

		while(myPointer->myAttributes.size() > 0)
		{
			XdmfAttribute * currAttribute = myPointer->myAttributes.back();

			std::stringstream attributeDataName;
			attributeDataName << myPointer->myName << ".h5:/" <<  totalGridName.str() << "/" << currAttribute->GetName();
			currAttribute->GetValues()->SetHeavyDataSetName(attributeDataName.str().c_str());

			grid->Insert(currAttribute);
			myPointer->myAttributes.pop_back();
		}

		grid->Build();
	}

	/**
	 *
	 * Write constructed Xdmf file to disk with filename created upon initialization
	 *
	 */
	void XdmfWriteToFile(long * pointer)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		std::stringstream dataName;
		dataName << myPointer->myName << ".xmf";
		myPointer->myDOM->Write(dataName.str().c_str());
	}

	/**
	 *
	 * Print current XdmfDOM to console
	 *
	 */
	void XdmfSerialize(long * pointer)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		cout << myPointer->myDOM->Serialize() << endl;
	}

	/**
	 *
	 * Copy current XdmfDOM to memory pointed to by charPointer
	 *
	 */
	void XdmfGetDOM(long * pointer, char * charPointer)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		strcpy(charPointer, myPointer->myDOM->Serialize());
	}

	/**
	 *
	 * Close XdmfFortran interface and clean memory
	 *
	 */
	void XdmfClose(long * pointer)
	{
		XdmfFortran * myPointer = (XdmfFortran *)*pointer;
		delete myPointer;
	}
}
<|endoftext|>


<commit_before>#include "catch.hpp"

#include "../src/statemachine.hpp"
#include <future>

using namespace fsm11;

namespace sync
{
using StateMachine_t = StateMachine<>;
using State_t = StateMachine_t::state_type;
} // namespace sync

namespace async
{
using StateMachine_t = StateMachine<AsynchronousEventDispatching,
                                    EnableConfigurationChangeCallbacks<true>>;
using State_t = StateMachine_t::state_type;
} // namespace async

TEST_CASE("construct a statemachine", "[statemachine]")
{
    using namespace sync;
    StateMachine_t sm;
    REQUIRE(!sm.running());
    REQUIRE(sm.numConfigurationChanges() == 0);
}

TEST_CASE("start an empty synchronous statemachine", "[statemachine]")
{
    using namespace sync;
    StateMachine_t sm;
    REQUIRE(!sm.running());
    REQUIRE(!sm.isActive());
    for (int cnt = 0; cnt < 2; ++cnt)
    {
        sm.start();
        REQUIRE(sm.running());
        REQUIRE(sm.isActive());
        REQUIRE(sm.numConfigurationChanges() == 2 * cnt + 1);
        sm.stop();
        REQUIRE(!sm.running());
        REQUIRE(!sm.isActive());
        REQUIRE(sm.numConfigurationChanges() == 2 * cnt + 2);
    }
}

TEST_CASE("start an empty asynchronous statemachine", "[statemachine]")
{
    using namespace async;
    StateMachine_t sm;

    std::mutex mutex;
    bool configurationChanged = false;
    std::condition_variable cv;

    sm.setConfigurationChangeCallback([&] {
        std::unique_lock<std::mutex> lock(mutex);
        configurationChanged = true;
        cv.notify_all();
    });

    auto waitForConfigurationChange = [&] {
        std::unique_lock<std::mutex> lock(mutex);
        cv.wait(lock, [&] { return configurationChanged; });
        configurationChanged = false;
    };

    REQUIRE(!sm.running());
    for (int cnt = 0; cnt < 2; ++cnt)
    {
        auto result = std::async(std::launch::async, &StateMachine_t::eventLoop, &sm);

        sm.start();
        waitForConfigurationChange();
        REQUIRE(sm.running());
        REQUIRE(sm.isActive());
        REQUIRE(sm.numConfigurationChanges() == 2 * cnt + 1);
        sm.stop();
        waitForConfigurationChange();
        REQUIRE(!sm.running());
        REQUIRE(!sm.isActive());
        REQUIRE(sm.numConfigurationChanges() == 2 * cnt + 2);
    }
}
<commit_msg>Added some basic test for the event-loop of an asynchronous statemachine.<commit_after>#include "catch.hpp"

#include "../src/statemachine.hpp"
#include <future>

using namespace fsm11;

namespace sync
{
using StateMachine_t = StateMachine<>;
using State_t = StateMachine_t::state_type;
} // namespace sync

namespace async
{
using StateMachine_t = StateMachine<AsynchronousEventDispatching,
                                    EnableConfigurationChangeCallbacks<true>>;
using State_t = StateMachine_t::state_type;
} // namespace async

TEST_CASE("construct a synchronous statemachine", "[statemachine]")
{
    using namespace sync;
    StateMachine_t sm;
    REQUIRE(!sm.running());
    REQUIRE(sm.numConfigurationChanges() == 0);
}

TEST_CASE("construct an asynchronous statemachine", "[statemachine]")
{
    using namespace async;
    StateMachine_t sm;
    REQUIRE(!sm.running());
    REQUIRE(sm.numConfigurationChanges() == 0);
}

TEST_CASE("the eventloop of an asynchronous statemachine is left upon destruction",
          "[statemachine]")
{
    std::future<void> result;

    {
        using namespace async;
        StateMachine_t sm;
        REQUIRE(!sm.running());
        REQUIRE(sm.numConfigurationChanges() == 0);

        result = std::async(std::launch::async, &StateMachine_t::eventLoop, &sm);
    }
}

TEST_CASE("start an empty synchronous statemachine", "[statemachine]")
{
    using namespace sync;
    StateMachine_t sm;
    REQUIRE(!sm.running());
    REQUIRE(!sm.isActive());
    for (int cnt = 0; cnt < 2; ++cnt)
    {
        sm.start();
        REQUIRE(sm.running());
        REQUIRE(sm.isActive());
        REQUIRE(sm.numConfigurationChanges() == 2 * cnt + 1);
        sm.stop();
        REQUIRE(!sm.running());
        REQUIRE(!sm.isActive());
        REQUIRE(sm.numConfigurationChanges() == 2 * cnt + 2);
    }
}

TEST_CASE("start an empty asynchronous statemachine", "[statemachine]")
{
    using namespace async;
    StateMachine_t sm;

    std::mutex mutex;
    bool configurationChanged = false;
    std::condition_variable cv;

    sm.setConfigurationChangeCallback([&] {
        std::unique_lock<std::mutex> lock(mutex);
        configurationChanged = true;
        cv.notify_all();
    });

    auto waitForConfigurationChange = [&] {
        std::unique_lock<std::mutex> lock(mutex);
        cv.wait(lock, [&] { return configurationChanged; });
        configurationChanged = false;
    };

    REQUIRE(!sm.running());
    for (int cnt = 0; cnt < 2; ++cnt)
    {
        auto result = std::async(std::launch::async, &StateMachine_t::eventLoop, &sm);

        sm.start();
        waitForConfigurationChange();
        REQUIRE(sm.running());
        REQUIRE(sm.isActive());
        REQUIRE(sm.numConfigurationChanges() == 2 * cnt + 1);
        sm.stop();
        waitForConfigurationChange();
        REQUIRE(!sm.running());
        REQUIRE(!sm.isActive());
        REQUIRE(sm.numConfigurationChanges() == 2 * cnt + 2);
    }
}

TEST_CASE("an asynchronous statemachine is stopped upon destruction",
          "[statemachine]")
{
    using namespace async;
    std::future<void> result;

    SECTION("without starting")
    {
        StateMachine_t sm;
        result = std::async(std::launch::async, &StateMachine_t::eventLoop, &sm);
    }

    SECTION("with starting")
    {
        StateMachine_t sm;
        result = std::async(std::launch::async, &StateMachine_t::eventLoop, &sm);
        sm.start();
    }
}
<|endoftext|>


<commit_before>
#include "cmath" // For isnan(), when it's defined

#include "diff_system.h"
#include "equation_systems.h"
#include "libmesh_logging.h"
#include "linear_solver.h"
#include "newton_solver.h"
#include "numeric_vector.h"
#include "sparse_matrix.h"
#include "dof_map.h"

NewtonSolver::NewtonSolver (sys_type& s)
  : Parent(s),
    require_residual_reduction(true),
    minsteplength(1e-5),
    linear_tolerance_multiplier(1e-3),
    linear_solver(LinearSolver<Number>::build())
{
}

NewtonSolver::~NewtonSolver ()
{
}

void NewtonSolver::reinit()
{
  Parent::reinit();

  linear_solver->clear();
}

void NewtonSolver::solve()
{
  START_LOG("solve()", "NewtonSolver");

  NumericVector<Number> &solution = *(_system.solution);
  NumericVector<Number> &newton_iterate =
    _system.get_vector("_nonlinear_solution");
  newton_iterate.close();
  solution.close();

  solution = newton_iterate;
  _system.get_dof_map().enforce_constraints_exactly(_system);
  newton_iterate = solution;

  NumericVector<Number> &rhs = *(_system.rhs);

  SparseMatrix<Number> &matrix = *(_system.matrix);

  // Prepare to take incomplete steps
  Real last_residual=0.;

  // Set starting linear tolerance
  Real current_linear_tolerance = initial_linear_tolerance;

  // Now we begin the nonlinear loop
  for (unsigned int l=0; l<max_nonlinear_iterations; ++l)
    {
      if (!quiet)
        std::cout << "Assembling System" << std::endl;

      PAUSE_LOG("solve()", "NewtonSolver");
      _system.assembly(true, true);
      RESTART_LOG("solve()", "NewtonSolver");
      rhs.close();
      Real current_residual = rhs.l2_norm();
      last_residual = current_residual;

// isnan() isn't standard C++ yet
#ifdef isnan
      if (isnan(current_residual))
        {
          std::cout << "  Nonlinear solver DIVERGED at step " << l
                    << " with norm Not-a-Number"
                    << std::endl;
          error();
          continue;
        }
#endif // isnan

      max_residual_norm = std::max (current_residual,
                                    max_residual_norm);

      // Compute the l2 norm of the whole solution
      Real norm_total = newton_iterate.l2_norm();

      max_solution_norm = std::max(max_solution_norm, norm_total);

      if (!quiet)
        std::cout << "Nonlinear Residual: "
                  << current_residual << std::endl;

      // Make sure our linear tolerance is low enough
      current_linear_tolerance = std::min (current_linear_tolerance,
        current_residual * linear_tolerance_multiplier);

      // But don't let it be zero
      if (current_linear_tolerance == 0.)
        {
          current_linear_tolerance = TOLERANCE * TOLERANCE;
        }

      // At this point newton_iterate is the current guess, and
      // solution is now about to become the NEGATIVE of the next
      // Newton step.

      // Our best initial guess for the solution is zero!
      solution.zero();

      if (!quiet)
        std::cout << "Linear solve starting" << std::endl;

      PAUSE_LOG("solve()", "NewtonSolver");
      // Solve the linear system.  Two cases:
      const std::pair<unsigned int, Real> rval =
        (_system.have_matrix("Preconditioner")) ?
      // 1.) User-supplied preconditioner
        linear_solver->solve (matrix, _system.get_matrix("Preconditioner"),
                              solution, rhs, current_linear_tolerance,
                              max_linear_iterations) :
      // 2.) Use system matrix for the preconditioner
        linear_solver->solve (matrix, solution, rhs,
                              current_linear_tolerance,
                              max_linear_iterations);
      // We may need to localize a parallel solution
      _system.update ();
      RESTART_LOG("solve()", "NewtonSolver");
      // The linear solver may not have fit our constraints exactly
      _system.get_dof_map().enforce_constraints_exactly(_system);

      const unsigned int linear_steps = rval.first;
      assert(linear_steps <= max_linear_iterations);
      const bool linear_solve_finished =
        !(linear_steps == max_linear_iterations);

      if (!quiet)
        std::cout << "Linear solve finished, step " << linear_steps
                  << ", residual " << rval.second
                  << ", tolerance " << current_linear_tolerance
                  << std::endl;

      // Compute the l2 norm of the nonlinear update
      Real norm_delta = solution.l2_norm();

      if (!quiet)
        std::cout << "Trying full Newton step" << std::endl;
      // Take a full Newton step
      newton_iterate.add (-1., solution);
      newton_iterate.close();

      // Check residual with full Newton step
      Real steplength = 1.;
      PAUSE_LOG("solve()", "NewtonSolver");
      _system.assembly(true, false);
      RESTART_LOG("solve()", "NewtonSolver");

      rhs.close();
      current_residual = rhs.l2_norm();

      // backtrack if necessary
      if (require_residual_reduction)
        {
          // but don't fiddle around if we've already converged
          if (test_convergence(current_residual, norm_delta,
                               linear_solve_finished))
            {
              if (!quiet)
		print_convergence(l, current_residual, norm_delta,
                                  linear_solve_finished);
              break;
            }

          while (current_residual > last_residual)
            {
              // Reduce step size to 1/2, 1/4, etc.
              steplength /= 2.;
              norm_delta /= 2.;
              if (!quiet)
                std::cout << "Shrinking Newton step to "
                          << steplength << std::endl;
              newton_iterate.add (steplength, solution);
              newton_iterate.close();

              // Check residual with fractional Newton step
              PAUSE_LOG("solve()", "NewtonSolver");
              _system.assembly (true, false);
              RESTART_LOG("solve()", "NewtonSolver");

              rhs.close();
              current_residual = rhs.l2_norm();
              if (!quiet)
                std::cout << "Current Residual: "
                          << current_residual << std::endl;

              if (steplength/2. < minsteplength &&
                  current_residual > last_residual)
                {
                  std::cout << "Inexact Newton step FAILED at step "
                            << l << std::endl;

                  error();
                }
            }
        }

      // Compute the l2 norm of the whole solution
      norm_total = newton_iterate.l2_norm();

      max_solution_norm = std::max(max_solution_norm, norm_total);

      // Print out information for the
      // nonlinear iterations.
      if (!quiet)
        std::cout << "  Nonlinear step: |du|/|u| = "
                  << norm_delta / norm_total
                  << ", |du| = " << norm_delta
                  << std::endl;

      // Terminate the solution iteration if the difference between
      // this iteration and the last is sufficiently small.
      if (!quiet)
        print_convergence(l, current_residual,
                          norm_delta / steplength,
                          linear_solve_finished);
      if (test_convergence(current_residual, norm_delta / steplength,
                           linear_solve_finished))
        {
          break;
        }
      if (l >= max_nonlinear_iterations - 1)
        {
          std::cout << "  Nonlinear solver FAILED TO CONVERGE by step " << l
                    << " with norm " << norm_total
                    << std::endl;
          error();
          continue;
        }
    } // end nonlinear loop

  // Copy the final nonlinear iterate into the current_solution,
  // for other libMesh functions that expect it

  solution = newton_iterate;
//  solution.close();

  // The linear solver may not have fit our constraints exactly
  _system.get_dof_map().enforce_constraints_exactly(_system);
  newton_iterate = solution;

  // We may need to localize a parallel solution
  _system.update ();

  STOP_LOG("solve()", "NewtonSolver");
}

bool NewtonSolver::test_convergence(Real current_residual,
                                    Real step_norm,
                                    bool linear_solve_finished)
{
  // We haven't converged unless we pass a convergence test
  bool has_converged = false;

  // Is our absolute residual low enough?
  if (current_residual < absolute_residual_tolerance)
    has_converged = true;

  // Is our relative residual low enough?
  if ((current_residual / max_residual_norm) <
      relative_residual_tolerance)
    has_converged = true;

  // For incomplete linear solves, it's not safe to test step sizes
  if (!linear_solve_finished)
    return has_converged;

  // Is our absolute Newton step size small enough?
  if (step_norm < absolute_step_tolerance)
    has_converged = true;

  // Is our relative Newton step size small enough?
  if (step_norm / max_solution_norm <
      relative_step_tolerance)
    has_converged = true;

  return has_converged;
}

void NewtonSolver::print_convergence(unsigned int step_num,
                                     Real current_residual,
                                     Real step_norm,
                                     bool linear_solve_finished)
{
  // Is our absolute residual low enough?
  if (current_residual < absolute_residual_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", residual " << current_residual
                << std::endl;
    }
  else if (absolute_residual_tolerance)
    {
      std::cout << "  Nonlinear solver current_residual "
                << current_residual << " > "
                << (absolute_residual_tolerance) << std::endl;
    }

  // Is our relative residual low enough?
  if ((current_residual / max_residual_norm) <
      relative_residual_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", residual reduction "
                << current_residual / max_residual_norm
                << " < " << relative_residual_tolerance
                << std::endl;
    }
  else if (relative_residual_tolerance)
    {
      if (!quiet)
        std::cout << "  Nonlinear solver relative residual "
                  << (current_residual / max_residual_norm)
                  << " > " << relative_residual_tolerance
                  << std::endl;
    }

  // For incomplete linear solves, it's not safe to test step sizes
  if (!linear_solve_finished)
    return;

  // Is our absolute Newton step size small enough?
  if (step_norm < absolute_step_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", absolute step size "
                << step_norm
                << " < " << absolute_step_tolerance
                << std::endl;
    }
  else if (absolute_step_tolerance)
    {
      std::cout << "  Nonlinear solver absolute step size "
                << step_norm
                << " > " << absolute_step_tolerance
                << std::endl;
    }

  // Is our relative Newton step size small enough?
  if (step_norm / max_solution_norm <
      relative_step_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", relative step size "
                << (step_norm / max_solution_norm)
                << " < " << relative_step_tolerance
                << std::endl;
    }
  else if (relative_step_tolerance)
    {
      std::cout << "  Nonlinear solver relative step size "
                << (step_norm / max_solution_norm)
                << " > " << relative_step_tolerance
                << std::endl;
    }
}
<commit_msg>More paranoia in parallel<commit_after>
#include "cmath" // For isnan(), when it's defined

#include "diff_system.h"
#include "equation_systems.h"
#include "libmesh_logging.h"
#include "linear_solver.h"
#include "newton_solver.h"
#include "numeric_vector.h"
#include "sparse_matrix.h"
#include "dof_map.h"

NewtonSolver::NewtonSolver (sys_type& s)
  : Parent(s),
    require_residual_reduction(true),
    minsteplength(1e-5),
    linear_tolerance_multiplier(1e-3),
    linear_solver(LinearSolver<Number>::build())
{
}

NewtonSolver::~NewtonSolver ()
{
}

void NewtonSolver::reinit()
{
  Parent::reinit();

  linear_solver->clear();
}

void NewtonSolver::solve()
{
  START_LOG("solve()", "NewtonSolver");

  NumericVector<Number> &solution = *(_system.solution);
  NumericVector<Number> &newton_iterate =
    _system.get_vector("_nonlinear_solution");
  newton_iterate.close();
  solution.close();

  solution = newton_iterate;
  _system.get_dof_map().enforce_constraints_exactly(_system);
  newton_iterate = solution;

  NumericVector<Number> &rhs = *(_system.rhs);

  SparseMatrix<Number> &matrix = *(_system.matrix);

  // Prepare to take incomplete steps
  Real last_residual=0.;

  // Set starting linear tolerance
  Real current_linear_tolerance = initial_linear_tolerance;

  // Now we begin the nonlinear loop
  for (unsigned int l=0; l<max_nonlinear_iterations; ++l)
    {
      if (!quiet)
        std::cout << "Assembling System" << std::endl;

      PAUSE_LOG("solve()", "NewtonSolver");
      _system.assembly(true, true);
      RESTART_LOG("solve()", "NewtonSolver");
      rhs.close();
      Real current_residual = rhs.l2_norm();
      last_residual = current_residual;

// isnan() isn't standard C++ yet
#ifdef isnan
      if (isnan(current_residual))
        {
          std::cout << "  Nonlinear solver DIVERGED at step " << l
                    << " with norm Not-a-Number"
                    << std::endl;
          error();
          continue;
        }
#endif // isnan

      max_residual_norm = std::max (current_residual,
                                    max_residual_norm);

      // Compute the l2 norm of the whole solution
      Real norm_total = newton_iterate.l2_norm();

      max_solution_norm = std::max(max_solution_norm, norm_total);

      if (!quiet)
        std::cout << "Nonlinear Residual: "
                  << current_residual << std::endl;

      // Make sure our linear tolerance is low enough
      current_linear_tolerance = std::min (current_linear_tolerance,
        current_residual * linear_tolerance_multiplier);

      // But don't let it be zero
      if (current_linear_tolerance == 0.)
        {
          current_linear_tolerance = TOLERANCE * TOLERANCE;
        }

      // At this point newton_iterate is the current guess, and
      // solution is now about to become the NEGATIVE of the next
      // Newton step.

      // Our best initial guess for the solution is zero!
      solution.zero();

      if (!quiet)
        std::cout << "Linear solve starting" << std::endl;

      PAUSE_LOG("solve()", "NewtonSolver");
      // Solve the linear system.  Two cases:
      const std::pair<unsigned int, Real> rval =
        (_system.have_matrix("Preconditioner")) ?
      // 1.) User-supplied preconditioner
        linear_solver->solve (matrix, _system.get_matrix("Preconditioner"),
                              solution, rhs, current_linear_tolerance,
                              max_linear_iterations) :
      // 2.) Use system matrix for the preconditioner
        linear_solver->solve (matrix, solution, rhs,
                              current_linear_tolerance,
                              max_linear_iterations);
      // We may need to localize a parallel solution
      _system.update ();
      RESTART_LOG("solve()", "NewtonSolver");
      // The linear solver may not have fit our constraints exactly
      _system.get_dof_map().enforce_constraints_exactly(_system);

      const unsigned int linear_steps = rval.first;
      assert(linear_steps <= max_linear_iterations);
      const bool linear_solve_finished =
        !(linear_steps == max_linear_iterations);

      if (!quiet)
        std::cout << "Linear solve finished, step " << linear_steps
                  << ", residual " << rval.second
                  << ", tolerance " << current_linear_tolerance
                  << std::endl;

      // Compute the l2 norm of the nonlinear update
      Real norm_delta = solution.l2_norm();

      if (!quiet)
        std::cout << "Trying full Newton step" << std::endl;
      // Take a full Newton step
      newton_iterate.add (-1., solution);
      newton_iterate.close();

      // Check residual with full Newton step
      Real steplength = 1.;
      PAUSE_LOG("solve()", "NewtonSolver");
      _system.assembly(true, false);
      RESTART_LOG("solve()", "NewtonSolver");

      rhs.close();
      current_residual = rhs.l2_norm();

      // backtrack if necessary
      if (require_residual_reduction)
        {
          // but don't fiddle around if we've already converged
          if (test_convergence(current_residual, norm_delta,
                               linear_solve_finished))
            {
              if (!quiet)
		print_convergence(l, current_residual, norm_delta,
                                  linear_solve_finished);
              break;
            }

          while (current_residual > last_residual)
            {
              // Reduce step size to 1/2, 1/4, etc.
              steplength /= 2.;
              norm_delta /= 2.;
              if (!quiet)
                std::cout << "Shrinking Newton step to "
                          << steplength << std::endl;
              newton_iterate.add (steplength, solution);
              newton_iterate.close();

              // Check residual with fractional Newton step
              PAUSE_LOG("solve()", "NewtonSolver");
              _system.assembly (true, false);
              RESTART_LOG("solve()", "NewtonSolver");

              rhs.close();
              current_residual = rhs.l2_norm();
              if (!quiet)
                std::cout << "Current Residual: "
                          << current_residual << std::endl;

              if (steplength/2. < minsteplength &&
                  current_residual > last_residual)
                {
                  std::cout << "Inexact Newton step FAILED at step "
                            << l << std::endl;

                  error();
                }
            }
        }

      // Compute the l2 norm of the whole solution
      norm_total = newton_iterate.l2_norm();

      max_solution_norm = std::max(max_solution_norm, norm_total);

      // Print out information for the
      // nonlinear iterations.
      if (!quiet)
        std::cout << "  Nonlinear step: |du|/|u| = "
                  << norm_delta / norm_total
                  << ", |du| = " << norm_delta
                  << std::endl;

      // Terminate the solution iteration if the difference between
      // this iteration and the last is sufficiently small.
      if (!quiet)
        print_convergence(l, current_residual,
                          norm_delta / steplength,
                          linear_solve_finished);
      if (test_convergence(current_residual, norm_delta / steplength,
                           linear_solve_finished))
        {
          break;
        }
      if (l >= max_nonlinear_iterations - 1)
        {
          std::cout << "  Nonlinear solver FAILED TO CONVERGE by step " << l
                    << " with norm " << norm_total
                    << std::endl;
          error();
          continue;
        }
    } // end nonlinear loop

  // Copy the final nonlinear iterate into the current_solution,
  // for other libMesh functions that expect it

  solution = newton_iterate;
  solution.close();

  // The linear solver may not have fit our constraints exactly
  _system.get_dof_map().enforce_constraints_exactly(_system);
  newton_iterate = solution;
  solution.close();

  // We may need to localize a parallel solution
  _system.update ();

  STOP_LOG("solve()", "NewtonSolver");
}

bool NewtonSolver::test_convergence(Real current_residual,
                                    Real step_norm,
                                    bool linear_solve_finished)
{
  // We haven't converged unless we pass a convergence test
  bool has_converged = false;

  // Is our absolute residual low enough?
  if (current_residual < absolute_residual_tolerance)
    has_converged = true;

  // Is our relative residual low enough?
  if ((current_residual / max_residual_norm) <
      relative_residual_tolerance)
    has_converged = true;

  // For incomplete linear solves, it's not safe to test step sizes
  if (!linear_solve_finished)
    return has_converged;

  // Is our absolute Newton step size small enough?
  if (step_norm < absolute_step_tolerance)
    has_converged = true;

  // Is our relative Newton step size small enough?
  if (step_norm / max_solution_norm <
      relative_step_tolerance)
    has_converged = true;

  return has_converged;
}

void NewtonSolver::print_convergence(unsigned int step_num,
                                     Real current_residual,
                                     Real step_norm,
                                     bool linear_solve_finished)
{
  // Is our absolute residual low enough?
  if (current_residual < absolute_residual_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", residual " << current_residual
                << std::endl;
    }
  else if (absolute_residual_tolerance)
    {
      std::cout << "  Nonlinear solver current_residual "
                << current_residual << " > "
                << (absolute_residual_tolerance) << std::endl;
    }

  // Is our relative residual low enough?
  if ((current_residual / max_residual_norm) <
      relative_residual_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", residual reduction "
                << current_residual / max_residual_norm
                << " < " << relative_residual_tolerance
                << std::endl;
    }
  else if (relative_residual_tolerance)
    {
      if (!quiet)
        std::cout << "  Nonlinear solver relative residual "
                  << (current_residual / max_residual_norm)
                  << " > " << relative_residual_tolerance
                  << std::endl;
    }

  // For incomplete linear solves, it's not safe to test step sizes
  if (!linear_solve_finished)
    return;

  // Is our absolute Newton step size small enough?
  if (step_norm < absolute_step_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", absolute step size "
                << step_norm
                << " < " << absolute_step_tolerance
                << std::endl;
    }
  else if (absolute_step_tolerance)
    {
      std::cout << "  Nonlinear solver absolute step size "
                << step_norm
                << " > " << absolute_step_tolerance
                << std::endl;
    }

  // Is our relative Newton step size small enough?
  if (step_norm / max_solution_norm <
      relative_step_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", relative step size "
                << (step_norm / max_solution_norm)
                << " < " << relative_step_tolerance
                << std::endl;
    }
  else if (relative_step_tolerance)
    {
      std::cout << "  Nonlinear solver relative step size "
                << (step_norm / max_solution_norm)
                << " > " << relative_step_tolerance
                << std::endl;
    }
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <fstream>
#include <util/functions.hpp>

#include <GL/glew.h>

#ifdef _WIN32
#   include <windows.h>
#elif __linux__
#include <GL/glx.h>
#elif __APPLE__

#endif

vector<cl_context_properties> pbdgpu::getOGLInteropInfo(cl_device_id &out_device)
{
	cl_device_id currentOGLDevice;
	cl_uint num_platforms;

	clGetPlatformIDs(0, nullptr, &num_platforms);

    vector<cl_platform_id> platforms(num_platforms);

    clGetPlatformIDs(num_platforms, &platforms[0], nullptr);

	for (unsigned int i = 0; i < num_platforms; ++i)
	{
		// get the function pointer for 'clGetGLContextInfoKHR' from the current platform
		clGetGLContextInfoKHR = reinterpret_cast<clGetGLContextInfoKHR_fn>(clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetGLContextInfoKHR"));
		if (!clGetGLContextInfoKHR)
		{
			continue;
		}

		// set up the required properties for 'clGetGLContextInfoKHR' and creation of a shared GL CL Context
        vector<cl_context_properties> properties = {
#ifdef _WIN32
			CL_GL_CONTEXT_KHR, reinterpret_cast<cl_context_properties>(wglGetCurrentContext()),
			CL_WGL_HDC_KHR, reinterpret_cast<cl_context_properties>(wglGetCurrentDC()),
			CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(platforms[i]),
#elif __linux__
			CL_GL_CONTEXT_KHR, reinterpret_cast<cl_context_properties>(glXGetCurrentContext()),
			CL_GLX_DISPLAY_KHR, reinterpret_cast<cl_context_properties>(glXGetCurrentDisplay()),
			CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(platforms[i]),
#elif __APPLE__
			CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
			reinterpret_cast<cl_context_properties>(CGLGetShareGroup(CGLGetCurrentContext())),
#endif
			0
		};

		size_t param_value_size_ret;
        clGetGLContextInfoKHR(&properties[0], CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_device_id), &currentOGLDevice, &param_value_size_ret);

		// This means for the current platform exists no which is currently associated with a OpenGL Context
		// -> Continue with next platform
		if (param_value_size_ret == 0) continue;

		// A suitable device was found
		out_device = currentOGLDevice;

        return properties;
	}

	fprintf(stderr,"Could not find a OpenCL platform with active OpenGL interop device.\nPlease Install the required OpenCL SDK's for your GPU or activate your preffered GPU (Dual-GPU Laptop)\n.");

    return vector<cl_context_properties>();
}

string pbdgpu::readFile(const string filename)
{
    std::ifstream ifs(filename);
    string content( (std::istreambuf_iterator<char>(ifs) ),
                    (std::istreambuf_iterator<char>()    ) );
    ifs.close();
    return content;
}

unsigned int pbdgpu::createShader(const string shaderSource, const unsigned int shaderType)
{
    unsigned int shaderID = glCreateShader(shaderType);
    const char* shaderSourcePtr = shaderSource.c_str();
    const int sourceSize = shaderSource.size();

    glShaderSource(shaderID, 1, &shaderSourcePtr, &sourceSize);
    glCompileShader(shaderID);

    GLint compilationSuccess = GL_FALSE;
    glGetShaderiv(shaderID, GL_COMPILE_STATUS, &compilationSuccess);
    if(compilationSuccess == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &maxLength);

        vector<char> errorLog(maxLength);
        glGetShaderInfoLog(shaderID, maxLength, &maxLength, &errorLog[0]);

        printf("%s",&errorLog[0]);

        glDeleteShader(shaderID);
        return 0;
    }
    return shaderID;
}

unsigned int pbdgpu::createProgram(const unsigned int vertexShader, const unsigned int hullShader, const unsigned int domainShader, const unsigned int fragmentShader)
{
    unsigned int programID = glCreateProgram();

    if(glIsShader(vertexShader))
    {
      glAttachShader(programID,vertexShader);
    }else{
        printf("createProgram: vertex shader invalid but program needs vertex shader. Linking aborted\n");
        return 0;
    }

    if(glIsShader(hullShader))
    {
        glAttachShader(programID,hullShader);
    }

    if(glIsShader(domainShader))
    {
        glAttachShader(programID,domainShader);
    }

    if(glIsShader(fragmentShader))
    {
        glAttachShader(programID,fragmentShader);
    }else{
        printf("createProgram: fragment shader invalid but program needs fragment shader. Linking aborted\n");
        return 0;
    }

    glLinkProgram(programID);

    GLint linkingSuccess = GL_FALSE;
    glGetProgramiv(programID, GL_LINK_STATUS, &linkingSuccess);
    if(linkingSuccess == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &maxLength);

        vector<char> errorLog(maxLength);
        glGetProgramInfoLog(programID, maxLength, &maxLength, &errorLog[0]);

        printf("%s",&errorLog[0]);

        glDeleteProgram(programID);

        return 0;
    }

    glDetachShader(programID,vertexShader);
    glDetachShader(programID,hullShader);
    glDetachShader(programID,domainShader);
    glDetachShader(programID,fragmentShader);

    return programID;
}

cl_kernel pbdgpu::createKernel(string kernelSource,string buildOptions, string kernelName, const cl_context context, const cl_device_id device){

    const char* sourcePtr = kernelSource.c_str();
    const size_t sourceSize = kernelSource.size();

    int err = CL_SUCCESS;
    cl_program kernelProgram = clCreateProgramWithSource(context,1,&sourcePtr,&sourceSize,&err);

    // compile an OpenCL Programm
    err = clBuildProgram(kernelProgram,1,&device,buildOptions.c_str(),NULL,NULL);
    if(err != 0)
    {
        size_t len;
        size_t retSourceSize;
        clGetProgramBuildInfo(kernelProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &len);
        clGetProgramInfo(kernelProgram,CL_PROGRAM_SOURCE,NULL,NULL,&retSourceSize);

        vector<char> BLog(len);
        vector<char> retSource(retSourceSize);
        clGetProgramBuildInfo(kernelProgram, device, CL_PROGRAM_BUILD_LOG, len, &BLog[0], NULL);
        clGetProgramInfo(kernelProgram,CL_PROGRAM_SOURCE,retSourceSize,&retSource[0],NULL);

        fprintf(stderr,"In Kernel Source ... \n\n%s\n\n ... occured the following Errors:\n\n%s", &retSource[0],&BLog[0]);

        return nullptr;
    }

    // create an OpenCL Kernel Object
    cl_kernel kernel = clCreateKernel(kernelProgram,kernelName.c_str(),&err);

    if(err != 0)
    {
        size_t retSourceSize;
        clGetProgramInfo(kernelProgram,CL_PROGRAM_SOURCE,NULL,NULL,&retSourceSize);

        vector<char> retSource(retSourceSize);
        clGetProgramInfo(kernelProgram,CL_PROGRAM_SOURCE,retSourceSize,&retSource[0],NULL);

        fprintf(stderr,"Error: %d while creating kernel: '%s'.\n\nFrom Source:\n%s",err,kernelName.c_str(),&retSource[0]);

        return nullptr;
    }
    return kernel;
}
<commit_msg>[Util] update utility functions<commit_after>#include <stdio.h>
#include <fstream>
#include <util/functions.hpp>

#include <GL/glew.h>

#ifdef _WIN32
#   include <windows.h>
#elif __linux__
#include <GL/glx.h>
#elif __APPLE__

#endif

vector<cl_context_properties> pbdgpu::getOGLInteropInfo(cl_device_id &out_device)
{
	cl_device_id currentOGLDevice;
	cl_uint num_platforms;

	clGetPlatformIDs(0, nullptr, &num_platforms);

    vector<cl_platform_id> platforms(num_platforms);

    clGetPlatformIDs(num_platforms, &platforms[0], nullptr);

	for (unsigned int i = 0; i < num_platforms; ++i)
	{
        size_t numChars;
        clGetPlatformInfo(platforms[i],CL_PLATFORM_EXTENSIONS,0, nullptr,&numChars);

        char* extensions = new char[numChars];

        clGetPlatformInfo(platforms[i],CL_PLATFORM_EXTENSIONS,numChars,extensions, nullptr);

        string extensionsString(extensions);

        if(extensionsString.find("cl_khr_gl_sharing") == std::string::npos)
        {
            continue;
        }

        clGetGLContextInfoKHR = nullptr;
		// get the function pointer for 'clGetGLContextInfoKHR' from the current platform
		clGetGLContextInfoKHR = reinterpret_cast<clGetGLContextInfoKHR_fn>(clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetGLContextInfoKHR"));
		if (!clGetGLContextInfoKHR)
		{
			continue;
		}

		// set up the required properties for 'clGetGLContextInfoKHR' and creation of a shared GL CL Context
        vector<cl_context_properties> properties = {
#ifdef _WIN32
			CL_GL_CONTEXT_KHR, reinterpret_cast<cl_context_properties>(wglGetCurrentContext()),
			CL_WGL_HDC_KHR, reinterpret_cast<cl_context_properties>(wglGetCurrentDC()),
			CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(platforms[i]),
#elif __linux__
			CL_GL_CONTEXT_KHR, reinterpret_cast<cl_context_properties>(glXGetCurrentContext()),
			CL_GLX_DISPLAY_KHR, reinterpret_cast<cl_context_properties>(glXGetCurrentDisplay()),
			CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(platforms[i]),
#elif __APPLE__
			CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
			reinterpret_cast<cl_context_properties>(CGLGetShareGroup(CGLGetCurrentContext())),
#endif
			0
		};

		size_t param_value_size_ret;
        clGetGLContextInfoKHR(&properties[0], CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_device_id), &currentOGLDevice, &param_value_size_ret);

		// This means for the current platform exists no which is currently associated with a OpenGL Context
		// -> Continue with next platform
		if (param_value_size_ret == 0) continue;

		// A suitable device was found
		out_device = currentOGLDevice;

        return properties;
	}

	fprintf(stderr,"Could not find a OpenCL platform with active OpenGL interop device.\nPlease Install the required OpenCL SDK's for your GPU or activate your preffered GPU (Dual-GPU Laptop)\n.");

    return vector<cl_context_properties>();
}

string pbdgpu::readFile(const string filename)
{
    std::ifstream ifs(filename);
    string content( (std::istreambuf_iterator<char>(ifs) ),
                    (std::istreambuf_iterator<char>()    ) );
    ifs.close();
    return content;
}

unsigned int pbdgpu::createShader(const string shaderSource, const unsigned int shaderType)
{
    unsigned int shaderID = glCreateShader(shaderType);
    const char* shaderSourcePtr = shaderSource.c_str();
    const int sourceSize = shaderSource.size();

    glShaderSource(shaderID, 1, &shaderSourcePtr, &sourceSize);
    glCompileShader(shaderID);

    GLint compilationSuccess = GL_FALSE;
    glGetShaderiv(shaderID, GL_COMPILE_STATUS, &compilationSuccess);
    if(compilationSuccess == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &maxLength);

        vector<char> errorLog(maxLength);
        glGetShaderInfoLog(shaderID, maxLength, &maxLength, &errorLog[0]);

        printf("-- Shader Error Log ---\n%s-----------------------\n",&errorLog[0]);

        glDeleteShader(shaderID);
        return 0;
    }
    return shaderID;
}

unsigned int pbdgpu::createProgram(const unsigned int vertexShader, const unsigned int hullShader, const unsigned int domainShader, const unsigned int fragmentShader)
{
    unsigned int programID = glCreateProgram();

    if(glIsShader(vertexShader))
    {
      glAttachShader(programID,vertexShader);
    }else{
        printf("createProgram: vertex shader invalid but program needs vertex shader. Linking aborted\n");
        return 0;
    }

    if(glIsShader(hullShader))
    {
        glAttachShader(programID,hullShader);
    }

    if(glIsShader(domainShader))
    {
        glAttachShader(programID,domainShader);
    }

    if(glIsShader(fragmentShader))
    {
        glAttachShader(programID,fragmentShader);
    }else{
        printf("createProgram: fragment shader invalid but program needs fragment shader. Linking aborted\n");
        return 0;
    }

    glLinkProgram(programID);

    GLint linkingSuccess = GL_FALSE;
    glGetProgramiv(programID, GL_LINK_STATUS, &linkingSuccess);
    if(linkingSuccess == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &maxLength);

        vector<char> errorLog(maxLength);
        glGetProgramInfoLog(programID, maxLength, &maxLength, &errorLog[0]);

        printf("%s",&errorLog[0]);

        glDeleteProgram(programID);

        return 0;
    }

    glDetachShader(programID,vertexShader);
    glDetachShader(programID,hullShader);
    glDetachShader(programID,domainShader);
    glDetachShader(programID,fragmentShader);

    return programID;
}

cl_kernel pbdgpu::createKernel(string kernelSource,string buildOptions, string kernelName, const cl_context context, const cl_device_id device){

    const char* sourcePtr = kernelSource.c_str();
    const size_t sourceSize = kernelSource.size();

    int err = CL_SUCCESS;
    cl_program kernelProgram = clCreateProgramWithSource(context,1,&sourcePtr,&sourceSize,&err);

    // compile an OpenCL Programm
    err = clBuildProgram(kernelProgram,1,&device,buildOptions.c_str(),NULL,NULL);
    if(err != 0)
    {
        size_t len;
        size_t retSourceSize;
        clGetProgramBuildInfo(kernelProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &len);
        clGetProgramInfo(kernelProgram,CL_PROGRAM_SOURCE,NULL,NULL,&retSourceSize);

        vector<char> BLog(len);
        vector<char> retSource(retSourceSize);
        clGetProgramBuildInfo(kernelProgram, device, CL_PROGRAM_BUILD_LOG, len, &BLog[0], NULL);
        clGetProgramInfo(kernelProgram,CL_PROGRAM_SOURCE,retSourceSize,&retSource[0],NULL);

        fprintf(stderr,"In Kernel Source ... \n\n%s\n\n ... occured the following Errors:\n\n%s", &retSource[0],&BLog[0]);

        return nullptr;
    }

    // create an OpenCL Kernel Object
    cl_kernel kernel = clCreateKernel(kernelProgram,kernelName.c_str(),&err);

    if(err != 0)
    {
        size_t retSourceSize;
        clGetProgramInfo(kernelProgram,CL_PROGRAM_SOURCE,NULL,NULL,&retSourceSize);

        vector<char> retSource(retSourceSize);
        clGetProgramInfo(kernelProgram,CL_PROGRAM_SOURCE,retSourceSize,&retSource[0],NULL);

        fprintf(stderr,"Error: %d while creating kernel: '%s'.\n\nFrom Source:\n%s",err,kernelName.c_str(),&retSource[0]);

        return nullptr;
    }
    return kernel;
}
<|endoftext|>


<commit_before>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "android_webview/crash_reporter/aw_microdump_crash_reporter.h"

#include "base/lazy_instance.h"
#include "components/crash/app/breakpad_linux.h"
#include "components/crash/app/crash_reporter_client.h"

namespace android_webview {
namespace crash_reporter {

namespace {

class AwCrashReporterClient : public ::crash_reporter::CrashReporterClient {
 public:
  AwCrashReporterClient() {}

  // crash_reporter::CrashReporterClient implementation.
  bool IsRunningUnattended() override { return false; }
  bool GetCollectStatsConsent() override { return false; }

  // Microdumps are always enabled in WebView builds, conversely to what happens
  // in the case of the other Chrome for Android builds (where they are enabled
  // only when NO_UNWIND_TABLES == 1).
  bool ShouldEnableBreakpadMicrodumps() override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(AwCrashReporterClient);
};

base::LazyInstance<AwCrashReporterClient>::Leaky g_crash_reporter_client =
    LAZY_INSTANCE_INITIALIZER;

bool g_enabled = false;

}  // namespace

void EnableMicrodumpCrashReporter() {
  if (g_enabled) {
    NOTREACHED() << "EnableMicrodumpCrashReporter called more than once";
    return;
  }

  ::crash_reporter::SetCrashReporterClient(g_crash_reporter_client.Pointer());

  // |process_type| is not really relevant here, as long as it not empty.
  breakpad::InitNonBrowserCrashReporterForAndroid("webview" /* process_type */);
  g_enabled = true;
}

}  // namespace crash_reporter
}  // namespace android_webview
<commit_msg>[android-webview] Disable breakpad microdumps on x86/64<commit_after>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "android_webview/crash_reporter/aw_microdump_crash_reporter.h"

#include "base/lazy_instance.h"
#include "build/build_config.h"
#include "components/crash/app/breakpad_linux.h"
#include "components/crash/app/crash_reporter_client.h"

namespace android_webview {
namespace crash_reporter {

namespace {

class AwCrashReporterClient : public ::crash_reporter::CrashReporterClient {
 public:
  AwCrashReporterClient() {}

  // crash_reporter::CrashReporterClient implementation.
  bool IsRunningUnattended() override { return false; }
  bool GetCollectStatsConsent() override { return false; }

  // Microdumps are always enabled in WebView builds, conversely to what happens
  // in the case of the other Chrome for Android builds (where they are enabled
  // only when NO_UNWIND_TABLES == 1).
  bool ShouldEnableBreakpadMicrodumps() override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(AwCrashReporterClient);
};

base::LazyInstance<AwCrashReporterClient>::Leaky g_crash_reporter_client =
    LAZY_INSTANCE_INITIALIZER;

bool g_enabled = false;

}  // namespace

void EnableMicrodumpCrashReporter() {
#if defined(ARCH_CPU_X86_FAMILY)
  // Don't install signal handler on X86/64 because this breaks binary
  // translators that handle SIGSEGV in userspace and get chained after our
  // handler. See crbug.com/477444
  return;
#endif

  if (g_enabled) {
    NOTREACHED() << "EnableMicrodumpCrashReporter called more than once";
    return;
  }

  ::crash_reporter::SetCrashReporterClient(g_crash_reporter_client.Pointer());

  // |process_type| is not really relevant here, as long as it not empty.
  breakpad::InitNonBrowserCrashReporterForAndroid("webview" /* process_type */);
  g_enabled = true;
}

}  // namespace crash_reporter
}  // namespace android_webview
<|endoftext|>


<commit_before>//#include "exception.h"
//For running at CERN
AliAnalysisTask *AddTaskDiHadron(){
  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_DiHadron", "No analysis manager found.");
    return 0;
  }

  //=========  Set initial parameters=====

  //Track Quality Cuts
  Int_t MinimumClustersTPC=70;
  Float_t MinClusterRatio=0.1;//1/2 would remove split tracks if not for sharing of clusters
  Float_t MaxTPCchi2=4;
  Int_t MinimumClustersITS=0;
  Float_t EtaCut=0.8;//Tracks in +/- Eta are used
  Float_t TriggerEtaCut=0.5;//Smaller trigger for flat acceptance on near-side
  Float_t NearPhiCut=1.5;//Cut used to seperate near and away side for delta eta plots
  Float_t XECut=NearPhiCut;//For XE distribution near and away seperation
  Float_t MaxDCA=3;//Total DCA Cut
  Float_t MaxDCAXY=2.4;
  Float_t MaxDCAZ=3.2;
  Int_t DCAMethod=2;//0 MaxDCA used, 1 MaxDCAXY and MaxDCAZ used 2 pT dependent DCA cut
  Int_t TPCRefit=1;
  Int_t ITSRefit=1;//1 for all particles, 2 for particles above 5 GeV/c
  Int_t SPDCut=1;//check for a point in 1 of first 2 layers of the its
 Float_t MinimumPt=0.25;//Minimum Pt considered by the code
  Float_t MaximumPt=50;
  Float_t ZVertexCut=10;//in cm

  Int_t EfficiencyCorrection=1;//do efficiency corrections in this code
  Int_t MakeMCHistos=1;//if 0 MC histograms are not made (will be empty if 1 and ran on real data)
  Int_t DEBUG=0;//for debugging

  //Binning
  Int_t nBinPhi=60;//Number of bins for #Delta#phi histograms
  Int_t nBinEta=54;//Number of bins for #Delta#eta histograms
  Int_t nBinsPhiEtaPhi=20;//Number of bins for #Delta#phi-#Delta#eta in #Delta#phi
  Int_t nBinsPhiEtaEta=18;//Number of bins for #Delta#phi-#Delta#eta in #Delta#phi
  Int_t nBinsPhiPhi=30;//Number of bins for #Delta#phi-#Delta#phi
  Int_t nBinsEtaEta=27;//Number of bins for #Delta#eta-#Delta#eta
  const Float_t fPi=3.1415926535898;
  Float_t PhiPlotMin=-fPi/3;//Min bin edge in #Delta#phi
  Float_t PhiPlotMax=2*fPi+PhiPlotMin;//Max bin edge

  //Size of some arrays change array contents below
  const Int_t NTriggerPtBins=12;//max=20
  const Int_t NEventsToMix=100;//max=100
  const Int_t NCentralityBins=4;//max=10
  const Int_t NAssociatedPtBins=25;//max=50
  const Int_t N3ParticleAssociatedPtBins=10;//max=50
  const Int_t NZVertexBinsForMixing=7;//max=20
  const Int_t NXEBins=11;//max=20
  const Int_t NumberOfTriggerIDs=1;
  Float_t EffFitPtCut=3;

  TF1 *EfficiencyFitLow=new TF1("EfficiencyFitLow","[0]/[1]*exp(-0.5*pow(x/[1],2))+[2]+[3]*x",MinimumPt,EffFitPtCut);
   TF1 *EfficiencyFitHigh=new TF1("EfficiencyFitHigh","[0]",EffFitPtCut,MaximumPt);
   const Int_t NParamFitLow=4;
   const Int_t NParamFitHigh=1;

   //Not high enough occupancy to worry about the centrality in pp
   //For overlapping centrality bins efficiencies from first bin are used
   //7Pythia_LHC10b5
   Float_t FitLowParam[NCentralityBins*NParamFitLow]={
     -0.030749, 0.254311, 0.858824, -0.0323708,
     -0.0304332, 0.252195, 0.851405, -0.03164,
     -0.0295618, 0.248594, 0.869159, -0.0354148,
     -0.0300529, 0.236693, 0.875875, -0.0370379};

   Float_t FitHighParam[NCentralityBins*NParamFitHigh]={
     0.75813,
     0.750521,
     0.751902,
     0.68658};

   /*
   //LHC10c6_900Pythia
   Float_t FitLowParam[NCentralityBins*NParamFitLow]={
     -0.027393, 0.236723, 0.814427, -0.023897,
     -0.0271116, 0.232689, 0.809889, -0.0246341,
     -0.0284658, 0.245163, 0.856043, -0.0318309,
     -0.117114, 0.0355117, 0.828829, -0.0207492}

   Float_t FightHighParam[NCentralityBins*NParamFitHigh]={
     0.729888,
     0.719402,
     0.708409,
     0.829268}
   */

  Float_t TriggerPtBins[(NTriggerPtBins+1)]={2,2.5,3,4,6,8,10,15,20,30,40,50};
  Float_t AssociatedPtBins[(NAssociatedPtBins+1)]={0.25,0.5,0.75,1,1.5,2,2.5,3,3.5,4,4.5,5,6,7,8,9,10,12,15,20,25,30,40,50,70,100};
  Float_t AssociatedPtBins31[N3ParticleAssociatedPtBins]={0.5,1.0,1.5,2.0,3,4,1};
  Float_t AssociatedPtBins32[N3ParticleAssociatedPtBins]={1.0,1.5,2.0,3.0,4,5,2};
  Int_t CentralityBins1[NCentralityBins]={0,     0, 20, 40};
  Int_t CentralityBins2[NCentralityBins]={500,20,40,500};
  Float_t XEBins[(NXEBins+1)]={0,0.05,0.1,0.15,0.2,0.3,0.4,0.5,0.6,0.7,0.8,1};
  char *TriggerIDArray[NumberOfTriggerIDs]={"CINT1B"};

  //==================================
  //Add the task
  //===================================
  AliAnalysisTaskDiHadron *task = new AliAnalysisTaskDiHadron("DiHadron");
  task->SetCuts(MinimumClustersTPC,MinClusterRatio,MaxTPCchi2,MinimumClustersITS, EtaCut,TriggerEtaCut,NearPhiCut,XECut,MaxDCA,MaxDCAXY,MaxDCAZ, DCAMethod, TPCRefit,ITSRefit,SPDCut,MinimumPt,MaximumPt,ZVertexCut,NumberOfTriggerIDs,TriggerIDArray);
  task->SetOptions(EfficiencyCorrection,DEBUG,MakeMCHistos);
  task->SetBins(nBinPhi,nBinEta,nBinsPhiEtaPhi,nBinsPhiEtaEta,nBinsPhiPhi,nBinsEtaEta,PhiPlotMin,PhiPlotMax,NTriggerPtBins,NEventsToMix,NCentralityBins,NAssociatedPtBins,N3ParticleAssociatedPtBins,NZVertexBinsForMixing,NXEBins,TriggerPtBins,AssociatedPtBins,AssociatedPtBins31,AssociatedPtBins32,CentralityBins1,CentralityBins2,XEBins);
  task->SetEfficiencies(EffFitPtCut,EfficiencyFitLow,EfficiencyFitHigh,NParamFitLow,NParamFitHigh,FitLowParam,FitHighParam);

  mgr->AddTask(task);

  //================================================
  //              data containers
  //================================================
 AliAnalysisDataContainer *cinput  = mgr->GetCommonInputContainer();
  mgr->ConnectInput(task, 0, cinput);

  //            define output containers, please use 'username'_'somename'
  AliAnalysisDataContainer *coutput1 =
    mgr->CreateContainer("DiHadron", TList::Class(),
			     AliAnalysisManager::kOutputContainer,"DiHadron.root");

  //           connect containers
  mgr->ConnectInput  (task,  0, cinput );
  mgr->ConnectOutput (task,  0, coutput1);

  return task;
}
<commit_msg>remove svn:executable<commit_after>//#include "exception.h"
//For running at CERN
AliAnalysisTask *AddTaskDiHadron(){
  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_DiHadron", "No analysis manager found.");
    return 0;
  }

  //=========  Set initial parameters=====

  //Track Quality Cuts
  Int_t MinimumClustersTPC=70;
  Float_t MinClusterRatio=0.1;//1/2 would remove split tracks if not for sharing of clusters
  Float_t MaxTPCchi2=4;
  Int_t MinimumClustersITS=0;
  Float_t EtaCut=0.8;//Tracks in +/- Eta are used
  Float_t TriggerEtaCut=0.5;//Smaller trigger for flat acceptance on near-side
  Float_t NearPhiCut=1.5;//Cut used to seperate near and away side for delta eta plots
  Float_t XECut=NearPhiCut;//For XE distribution near and away seperation
  Float_t MaxDCA=3;//Total DCA Cut
  Float_t MaxDCAXY=2.4;
  Float_t MaxDCAZ=3.2;
  Int_t DCAMethod=2;//0 MaxDCA used, 1 MaxDCAXY and MaxDCAZ used 2 pT dependent DCA cut
  Int_t TPCRefit=1;
  Int_t ITSRefit=1;//1 for all particles, 2 for particles above 5 GeV/c
  Int_t SPDCut=1;//check for a point in 1 of first 2 layers of the its
 Float_t MinimumPt=0.25;//Minimum Pt considered by the code
  Float_t MaximumPt=50;
  Float_t ZVertexCut=10;//in cm

  Int_t EfficiencyCorrection=1;//do efficiency corrections in this code
  Int_t MakeMCHistos=1;//if 0 MC histograms are not made (will be empty if 1 and ran on real data)
  Int_t DEBUG=0;//for debugging

  //Binning
  Int_t nBinPhi=60;//Number of bins for #Delta#phi histograms
  Int_t nBinEta=54;//Number of bins for #Delta#eta histograms
  Int_t nBinsPhiEtaPhi=20;//Number of bins for #Delta#phi-#Delta#eta in #Delta#phi
  Int_t nBinsPhiEtaEta=18;//Number of bins for #Delta#phi-#Delta#eta in #Delta#phi
  Int_t nBinsPhiPhi=30;//Number of bins for #Delta#phi-#Delta#phi
  Int_t nBinsEtaEta=27;//Number of bins for #Delta#eta-#Delta#eta
  const Float_t fPi=3.1415926535898;
  Float_t PhiPlotMin=-fPi/3;//Min bin edge in #Delta#phi
  Float_t PhiPlotMax=2*fPi+PhiPlotMin;//Max bin edge

  //Size of some arrays change array contents below
  const Int_t NTriggerPtBins=12;//max=20
  const Int_t NEventsToMix=100;//max=100
  const Int_t NCentralityBins=4;//max=10
  const Int_t NAssociatedPtBins=25;//max=50
  const Int_t N3ParticleAssociatedPtBins=10;//max=50
  const Int_t NZVertexBinsForMixing=7;//max=20
  const Int_t NXEBins=11;//max=20
  const Int_t NumberOfTriggerIDs=1;
  Float_t EffFitPtCut=3;

  TF1 *EfficiencyFitLow=new TF1("EfficiencyFitLow","[0]/[1]*exp(-0.5*pow(x/[1],2))+[2]+[3]*x",MinimumPt,EffFitPtCut);
   TF1 *EfficiencyFitHigh=new TF1("EfficiencyFitHigh","[0]",EffFitPtCut,MaximumPt);
   const Int_t NParamFitLow=4;
   const Int_t NParamFitHigh=1;

   //Not high enough occupancy to worry about the centrality in pp
   //For overlapping centrality bins efficiencies from first bin are used
   //7Pythia_LHC10b5
   Float_t FitLowParam[NCentralityBins*NParamFitLow]={
     -0.030749, 0.254311, 0.858824, -0.0323708,
     -0.0304332, 0.252195, 0.851405, -0.03164,
     -0.0295618, 0.248594, 0.869159, -0.0354148,
     -0.0300529, 0.236693, 0.875875, -0.0370379};

   Float_t FitHighParam[NCentralityBins*NParamFitHigh]={
     0.75813,
     0.750521,
     0.751902,
     0.68658};

   /*
   //LHC10c6_900Pythia
   Float_t FitLowParam[NCentralityBins*NParamFitLow]={
     -0.027393, 0.236723, 0.814427, -0.023897,
     -0.0271116, 0.232689, 0.809889, -0.0246341,
     -0.0284658, 0.245163, 0.856043, -0.0318309,
     -0.117114, 0.0355117, 0.828829, -0.0207492}

   Float_t FightHighParam[NCentralityBins*NParamFitHigh]={
     0.729888,
     0.719402,
     0.708409,
     0.829268}
   */

  Float_t TriggerPtBins[(NTriggerPtBins+1)]={2,2.5,3,4,6,8,10,15,20,30,40,50};
  Float_t AssociatedPtBins[(NAssociatedPtBins+1)]={0.25,0.5,0.75,1,1.5,2,2.5,3,3.5,4,4.5,5,6,7,8,9,10,12,15,20,25,30,40,50,70,100};
  Float_t AssociatedPtBins31[N3ParticleAssociatedPtBins]={0.5,1.0,1.5,2.0,3,4,1};
  Float_t AssociatedPtBins32[N3ParticleAssociatedPtBins]={1.0,1.5,2.0,3.0,4,5,2};
  Int_t CentralityBins1[NCentralityBins]={0,     0, 20, 40};
  Int_t CentralityBins2[NCentralityBins]={500,20,40,500};
  Float_t XEBins[(NXEBins+1)]={0,0.05,0.1,0.15,0.2,0.3,0.4,0.5,0.6,0.7,0.8,1};
  char *TriggerIDArray[NumberOfTriggerIDs]={"CINT1B"};

  //==================================
  //Add the task
  //===================================
  AliAnalysisTaskDiHadron *task = new AliAnalysisTaskDiHadron("DiHadron");
  task->SetCuts(MinimumClustersTPC,MinClusterRatio,MaxTPCchi2,MinimumClustersITS, EtaCut,TriggerEtaCut,NearPhiCut,XECut,MaxDCA,MaxDCAXY,MaxDCAZ, DCAMethod, TPCRefit,ITSRefit,SPDCut,MinimumPt,MaximumPt,ZVertexCut,NumberOfTriggerIDs,TriggerIDArray);
  task->SetOptions(EfficiencyCorrection,DEBUG,MakeMCHistos);
  task->SetBins(nBinPhi,nBinEta,nBinsPhiEtaPhi,nBinsPhiEtaEta,nBinsPhiPhi,nBinsEtaEta,PhiPlotMin,PhiPlotMax,NTriggerPtBins,NEventsToMix,NCentralityBins,NAssociatedPtBins,N3ParticleAssociatedPtBins,NZVertexBinsForMixing,NXEBins,TriggerPtBins,AssociatedPtBins,AssociatedPtBins31,AssociatedPtBins32,CentralityBins1,CentralityBins2,XEBins);
  task->SetEfficiencies(EffFitPtCut,EfficiencyFitLow,EfficiencyFitHigh,NParamFitLow,NParamFitHigh,FitLowParam,FitHighParam);

  mgr->AddTask(task);

  //================================================
  //              data containers
  //================================================
 AliAnalysisDataContainer *cinput  = mgr->GetCommonInputContainer();
  mgr->ConnectInput(task, 0, cinput);

  //            define output containers, please use 'username'_'somename'
  AliAnalysisDataContainer *coutput1 =
    mgr->CreateContainer("DiHadron", TList::Class(),
			     AliAnalysisManager::kOutputContainer,"DiHadron.root");

  //           connect containers
  mgr->ConnectInput  (task,  0, cinput );
  mgr->ConnectOutput (task,  0, coutput1);

  return task;
}
<|endoftext|>


<commit_before>/*
 *     Copyright (C) 2005 by Thorsten Staerk <kde@staerk.de>
 *                   2007 the ktimetracker developers
 *
 *   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.
 *
 */

#include "karm_part.h"

#include <QMenu>

#include <KAboutData>
#include <KAction>
#include <KComponentData>
#include <KGlobal>
#include <KLocale>
#include <KStandardAction>
#include <KStandardDirs>
#include <KXMLGUIFactory>
#include <KActionCollection>

#include <kdemacros.h>
#include <kparts/genericfactory.h>
#include "mainwindow.h"
#include "karmerrors.h"
#include "task.h"
#include "preferences.h"
#include "tray.h"
#include "version.h"
#include "ktimetracker.h"
#include "timetrackerwidget.h"

K_PLUGIN_FACTORY(karmPartFactory, registerPlugin<karmPart>();)
K_EXPORT_PLUGIN( karmPartFactory )

karmPart::karmPart( QWidget *parentWidget, QObject *parent, const QVariantList& )
    : KParts::ReadWritePart(parent)
{
  // we need an instance
  setComponentData( karmPartFactory::componentData() );

  mMainWidget = new TimetrackerWidget( parentWidget );
  setWidget( mMainWidget );
  makeMenus();
  mMainWidget->openFile( KStandardDirs::locateLocal( "appdata",
                        QString::fromLatin1( "karm.ics" ) ) );

  // connections
  connect( mMainWidget, SIGNAL( totalTimesChanged( long, long ) ),
           this, SLOT( updateTime( long, long ) ) );
  connect( mMainWidget, SIGNAL( statusBarTextChangeRequested( QString ) ),
                 this, SLOT( setStatusBar( QString ) ) );

  // Setup context menu request handling
  connect( mMainWidget,
           SIGNAL( contextMenuRequested( const QPoint& ) ),
           this,
           SLOT( taskViewCustomContextMenuRequested( const QPoint& ) ) );

  if ( KTimeTrackerSettings::trayIcon() ) mTray = new TrayIcon( this );
  else mTray = new TrayIcon( );

  connect( mTray, SIGNAL( quitSelected() ), SLOT( quit() ) );

  connect( mMainWidget, SIGNAL( timersActive() ), mTray, SLOT( startClock() ) );
  connect( mMainWidget, SIGNAL( timersInactive() ), mTray, SLOT( stopClock() ) );
  connect( mMainWidget, SIGNAL( tasksChanged( const QList<Task*>& ) ),
           mTray, SLOT( updateToolTip( QList<Task*> ) ));
}

karmPart::~karmPart()
{
}

KAboutData *karmPart::createAboutData()
{
  const QByteArray& ba=QByteArray("test");
  const KLocalizedString name=ki18n("myName");
  KAboutData* aboutData=new KAboutData( ba, ba, name, ba, name);
  return aboutData;
  //return KABCore::createAboutData();
  #warning not implemented
}

void karmPart::makeMenus()
{
  mMainWidget->setupActions( actionCollection() );
  KAction *actionKeyBindings;

  actionKeyBindings = KStandardAction::keyBindings( this, SLOT( keyBindings() ),
      actionCollection() );

  setXMLFile( QString::fromLatin1( "karmui.rc" ) );

  // Tool tops must be set after the createGUI.
  actionKeyBindings->setToolTip( i18n("Configure key bindings") );
  actionKeyBindings->setWhatsThis( i18n("This will let you configure key"
                                        "bindings which are specific to ktimetracker") );
}

void karmPart::setStatusBar(const QString & qs)
{
  kDebug(5970) << "Entering function";
  emit setStatusBarText(qs);
}

bool karmPart::openFile()
{
  mMainWidget->openFile();

  return true;
}

bool karmPart::saveFile()
{
  mMainWidget->saveFile();

  return true;
}

extern "C"
{
    KDE_EXPORT void* init_karmpart()
    {
	KGlobal::locale()->insertCatalog("karm");
        return new karmPartFactory;
    }
}

void karmPart::taskViewCustomContextMenuRequested( const QPoint& point )
{
    QMenu* pop = dynamic_cast<QMenu*>(
                          factory()->container( i18n( "task_popup" ), this ) );
    if ( pop )
      pop->popup( point );
}

#include "karm_part.moc"
<commit_msg>init_*() entry point not needed as we have K_EXPORT_PLUGIN<commit_after>/*
 *     Copyright (C) 2005 by Thorsten Staerk <kde@staerk.de>
 *                   2007 the ktimetracker developers
 *
 *   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.
 *
 */

#include "karm_part.h"

#include <QMenu>

#include <KAboutData>
#include <KAction>
#include <KComponentData>
#include <KGlobal>
#include <KLocale>
#include <KStandardAction>
#include <KStandardDirs>
#include <KXMLGUIFactory>
#include <KActionCollection>

#include <kdemacros.h>
#include <kparts/genericfactory.h>
#include "mainwindow.h"
#include "karmerrors.h"
#include "task.h"
#include "preferences.h"
#include "tray.h"
#include "version.h"
#include "ktimetracker.h"
#include "timetrackerwidget.h"

K_PLUGIN_FACTORY(karmPartFactory, registerPlugin<karmPart>();)
K_EXPORT_PLUGIN( karmPartFactory )

karmPart::karmPart( QWidget *parentWidget, QObject *parent, const QVariantList& )
    : KParts::ReadWritePart(parent)
{
  KGlobal::locale()->insertCatalog("karm");

  // we need an instance
  setComponentData( karmPartFactory::componentData() );

  mMainWidget = new TimetrackerWidget( parentWidget );
  setWidget( mMainWidget );
  makeMenus();
  mMainWidget->openFile( KStandardDirs::locateLocal( "appdata",
                        QString::fromLatin1( "karm.ics" ) ) );

  // connections
  connect( mMainWidget, SIGNAL( totalTimesChanged( long, long ) ),
           this, SLOT( updateTime( long, long ) ) );
  connect( mMainWidget, SIGNAL( statusBarTextChangeRequested( QString ) ),
                 this, SLOT( setStatusBar( QString ) ) );

  // Setup context menu request handling
  connect( mMainWidget,
           SIGNAL( contextMenuRequested( const QPoint& ) ),
           this,
           SLOT( taskViewCustomContextMenuRequested( const QPoint& ) ) );

  if ( KTimeTrackerSettings::trayIcon() ) mTray = new TrayIcon( this );
  else mTray = new TrayIcon( );

  connect( mTray, SIGNAL( quitSelected() ), SLOT( quit() ) );

  connect( mMainWidget, SIGNAL( timersActive() ), mTray, SLOT( startClock() ) );
  connect( mMainWidget, SIGNAL( timersInactive() ), mTray, SLOT( stopClock() ) );
  connect( mMainWidget, SIGNAL( tasksChanged( const QList<Task*>& ) ),
           mTray, SLOT( updateToolTip( QList<Task*> ) ));
}

karmPart::~karmPart()
{
}

KAboutData *karmPart::createAboutData()
{
  const QByteArray& ba=QByteArray("test");
  const KLocalizedString name=ki18n("myName");
  KAboutData* aboutData=new KAboutData( ba, ba, name, ba, name);
  return aboutData;
  //return KABCore::createAboutData();
  #warning not implemented
}

void karmPart::makeMenus()
{
  mMainWidget->setupActions( actionCollection() );
  KAction *actionKeyBindings;

  actionKeyBindings = KStandardAction::keyBindings( this, SLOT( keyBindings() ),
      actionCollection() );

  setXMLFile( QString::fromLatin1( "karmui.rc" ) );

  // Tool tops must be set after the createGUI.
  actionKeyBindings->setToolTip( i18n("Configure key bindings") );
  actionKeyBindings->setWhatsThis( i18n("This will let you configure key"
                                        "bindings which are specific to ktimetracker") );
}

void karmPart::setStatusBar(const QString & qs)
{
  kDebug(5970) << "Entering function";
  emit setStatusBarText(qs);
}

bool karmPart::openFile()
{
  mMainWidget->openFile();

  return true;
}

bool karmPart::saveFile()
{
  mMainWidget->saveFile();

  return true;
}

void karmPart::taskViewCustomContextMenuRequested( const QPoint& point )
{
    QMenu* pop = dynamic_cast<QMenu*>(
                          factory()->container( i18n( "task_popup" ), this ) );
    if ( pop )
      pop->popup( point );
}

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