<commit_before>// now in options
//=============================================//
//const char* centralityEstimator = "V0M";
//const char* centralityEstimator = "CL1";
//const char* centralityEstimator = "TRK";
//=============================================//
//Bool_t gRunShuffling = kFALSE;
//Bool_t gRunShuffling = kTRUE;
//=============================================//

//PID config
Bool_t kUseNSigmaPID = kFALSE;
Double_t nSigmaMax = 3.0;
Bool_t kUseBayesianPID = kTRUE;
Double_t gMinAcceptedProbability = 0.7;

//_________________________________________________________//
AliAnalysisTaskBFPsi *AddTaskBalancePsiCentralityTrain(Double_t centrMin=0.,
						       Double_t centrMax=100.,
						       Bool_t gRunShuffling=kFALSE,
						       Bool_t gRunMixing=kFALSE,
						       Bool_t gRunMixingWithEventPlane=kFALSE,
						       TString centralityEstimator="V0M",
						       Double_t vertexZ=10.,
						       Double_t DCAxy=-1,
						       Double_t DCAz=-1,
						       Double_t ptMin=0.3,
						       Double_t ptMax=1.5,
						       Double_t etaMin=-0.8,
						       Double_t etaMax=0.8,
						       Double_t maxTPCchi2 = -1,
						       Int_t minNClustersTPC = -1,
						       Bool_t kUsePID = kFALSE,
						       Bool_t bResonancesCut = kFALSE,
						       Bool_t bHBTcut = kFALSE,
						       Bool_t bConversionCut = kFALSE,

						       Bool_t bMomentumDifferenceCut = kFALSE,
						       Int_t AODfilterBit = 128,
						       Bool_t bCentralTrigger = kFALSE,
						       TString fileNameBase="AnalysisResults",
						       TString fArgEventClass="Centrality",
						       TString analysisTypeUser="",
						       Bool_t bVertexBinning=kFALSE) {
  // Creates a balance function analysis task and adds it to the analysis manager.
  // Get the pointer to the existing analysis manager via the static access method.
  TString outputFileName(fileNameBase);
  outputFileName.Append(".root");

  //===========================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskBF", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //===========================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddTaskBF", "This task requires an input event handler");
    return NULL;
  }
  TString analysisType = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
  if(dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())) analysisType = "MC";

  // to set the analysis type manually
  if(analysisTypeUser != ""){
    analysisType = analysisTypeUser;
    ::Info("AddTaskBF",Form("Analysis Type manually set to %s",analysisType.Data()));
  }

  // for local changed BF configuration
  //gROOT->LoadMacro("./configBalanceFunctionPsiAnalysis.C");
  gROOT->LoadMacro("$ALICE_ROOT/PWGCF/EBYE/macros/configBalanceFunctionPsiAnalysis.C");
  AliBalancePsi *bf  = 0;  // Balance Function object
  AliBalancePsi *bfs = 0;  // shuffled Balance function object
  AliBalancePsi *bfm = 0;  // mixing Balance function object

  //maximum Delta eta range
  Double_t deltaEtaMax=TMath::Abs(etaMax-etaMin);

  if (analysisType=="ESD"){
    bf  = GetBalanceFunctionObject("ESD",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunShuffling) bfs = GetBalanceFunctionObject("ESD",centralityEstimator,centrMin,centrMax,kTRUE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunMixing)    bfm = GetBalanceFunctionObject("ESD",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
  }
  else if (analysisType=="AOD"){
    bf  = GetBalanceFunctionObject("AOD",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunShuffling) bfs = GetBalanceFunctionObject("AOD",centralityEstimator,centrMin,centrMax,kTRUE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunMixing)    bfm = GetBalanceFunctionObject("AOD",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
  }
  else if (analysisType=="MC"){
    bf  = GetBalanceFunctionObject("MC",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunShuffling) bfs = GetBalanceFunctionObject("MC",centralityEstimator,centrMin,centrMax,kTRUE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunMixing)    bfm = GetBalanceFunctionObject("MC",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
  }
  else{
    ::Error("AddTaskBF", "analysis type NOT known.");
    return NULL;
  }

  // Create the task, add it to manager and configure it.
  //===========================================================================
  AliAnalysisTaskBFPsi *taskBF = new AliAnalysisTaskBFPsi("TaskBFPsi");

  //Event characteristics scheme
  taskBF->SetEventClass(fArgEventClass);
  if(fArgEventClass == "Multiplicity")
    taskBF->SetMultiplicityRange(centrMin,centrMax);
  else
    taskBF->SetCentralityPercentileRange(centrMin,centrMax);

  taskBF->SetAnalysisObject(bf);
  if(gRunShuffling) taskBF->SetShufflingObject(bfs);
  if(gRunMixing){
    taskBF->SetMixingObject(bfm);
    taskBF->SetMixingTracks(50000);
    if(gRunMixingWithEventPlane){
      taskBF->SetMixingWithEventPlane(gRunMixingWithEventPlane);
    }
  }

  if(analysisType == "ESD") {
    AliESDtrackCuts *trackCuts = GetTrackCutsObject(ptMin,ptMax,etaMin,etaMax,maxTPCchi2,DCAxy,DCAz,minNClustersTPC);
    taskBF->SetAnalysisCutObject(trackCuts);
    if(kUsePID) {
      if(kUseBayesianPID)
	taskBF->SetUseBayesianPID(gMinAcceptedProbability);
      else if(kUseNSigmaPID)
	taskBF->SetUseNSigmaPID(nSigmaMax);
      taskBF->SetParticleOfInterest(AliAnalysistaskBFPsi::kProton);
      taskBF->SetDetectorUsedForPID(AliAnalysisTaskBFPsi::kTOFpid);
    }
  }
  else if(analysisType == "AOD") {
    // pt and eta cut (pt_min, pt_max, eta_min, eta_max)
    taskBF->SetAODtrackCutBit(AODfilterBit);
    taskBF->SetKinematicsCutsAOD(ptMin,ptMax,etaMin,etaMax);

    // set extra DCA cuts (-1 no extra cut)
    taskBF->SetExtraDCACutsAOD(DCAxy,DCAz);

    // set extra TPC chi2 / nr of clusters cut
    taskBF->SetExtraTPCCutsAOD(maxTPCchi2, minNClustersTPC);

  }
  else if(analysisType == "MC") {
    taskBF->SetKinematicsCutsAOD(ptMin,ptMax,etaMin,etaMax);
    taskBF->SetImpactParameterRange(centrMin,centrMax);
  }

  // offline trigger selection (AliVEvent.h)
  // taskBF->UseOfflineTrigger(); // NOT used (selection is done with the AliAnalysisTaskSE::SelectCollisionCandidates())
  // with this only selected events are analyzed (first 2 bins in event QA histogram are the same))
  // documentation in https://twiki.cern.ch/twiki/bin/viewauth/ALICE/PWG1EvSelDocumentation
  if(bCentralTrigger) taskBF->SelectCollisionCandidates(AliVEvent::kMB | AliVEvent::kCentral | AliVEvent::kSemiCentral);
  else                taskBF->SelectCollisionCandidates(AliVEvent::kMB);

  // centrality estimator (default = V0M)
  taskBF->SetCentralityEstimator(centralityEstimator);

  // vertex cut (x,y,z)
  taskBF->SetVertexDiamond(.3,.3,vertexZ);

  //bf->PrintAnalysisSettings();
  mgr->AddTask(taskBF);

  // Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================
  TString outputFileName = AliAnalysisManager::GetCommonFileName();
  outputFileName += ":PWGCFEbyE.outputBalanceFunctionPsiAnalysis";
  AliAnalysisDataContainer *coutQA = mgr->CreateContainer(Form("listQAPsi_%.0f-%.0f_Bit%d_%s",centrMin,centrMax,AODfilterBit,centralityEstimator.Data()), TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());
  AliAnalysisDataContainer *coutBF = mgr->CreateContainer(Form("listBFPsi_%.0f-%.0f_Bit%d_%s",centrMin,centrMax,AODfilterBit,centralityEstimator.Data()), TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());
  if(gRunShuffling) AliAnalysisDataContainer *coutBFS = mgr->CreateContainer(Form("listBFPsiShuffled_%.0f-%.0f_Bit%d_%s",centrMin,centrMax,AODfilterBit,centralityEstimator.Data()), TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());
  if(gRunMixing) AliAnalysisDataContainer *coutBFM = mgr->CreateContainer(Form("listBFPsiMixed_%.0f-%.0f_Bit%d_%s",centrMin,centrMax,AODfilterBit,centralityEstimator.Data()), TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());
  if(kUsePID) AliAnalysisDataContainer *coutQAPID = mgr->CreateContainer(Form("listQAPIDPsi_%.0f-%.0f_Bit%d_%s",centrMin,centrMax,AODfilterBit,centralityEstimator.Data()), TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());

  mgr->ConnectInput(taskBF, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(taskBF, 1, coutQA);
  mgr->ConnectOutput(taskBF, 2, coutBF);
  if(gRunShuffling) mgr->ConnectOutput(taskBF, 3, coutBFS);
  if(gRunMixing) mgr->ConnectOutput(taskBF, 4, coutBFM);
  if(kUsePID && analysisType == "ESD") mgr->ConnectOutput(taskBF, 5, coutQAPID);

  return taskBF;
}
<commit_msg>Proper reference multiplicity in case of MC analysis (pp)<commit_after>// now in options
//=============================================//
//const char* centralityEstimator = "V0M";
//const char* centralityEstimator = "CL1";
//const char* centralityEstimator = "TRK";
//=============================================//
//Bool_t gRunShuffling = kFALSE;
//Bool_t gRunShuffling = kTRUE;
//=============================================//

//PID config
Bool_t kUseNSigmaPID = kFALSE;
Double_t nSigmaMax = 3.0;
Bool_t kUseBayesianPID = kTRUE;
Double_t gMinAcceptedProbability = 0.7;

//_________________________________________________________//
AliAnalysisTaskBFPsi *AddTaskBalancePsiCentralityTrain(Double_t centrMin=0.,
						       Double_t centrMax=100.,
						       Bool_t gRunShuffling=kFALSE,
						       Bool_t gRunMixing=kFALSE,
						       Bool_t gRunMixingWithEventPlane=kFALSE,
						       TString centralityEstimator="V0M",
						       Double_t vertexZ=10.,
						       Double_t DCAxy=-1,
						       Double_t DCAz=-1,
						       Double_t ptMin=0.3,
						       Double_t ptMax=1.5,
						       Double_t etaMin=-0.8,
						       Double_t etaMax=0.8,
						       Double_t maxTPCchi2 = -1,
						       Int_t minNClustersTPC = -1,
						       Bool_t kUsePID = kFALSE,
						       Bool_t bResonancesCut = kFALSE,
						       Bool_t bHBTcut = kFALSE,
						       Bool_t bConversionCut = kFALSE,

						       Bool_t bMomentumDifferenceCut = kFALSE,
						       Int_t AODfilterBit = 128,
						       Bool_t bCentralTrigger = kFALSE,
						       TString fileNameBase="AnalysisResults",
						       TString fArgEventClass="Centrality",
						       TString analysisTypeUser="",
						       Bool_t bVertexBinning=kFALSE) {
  // Creates a balance function analysis task and adds it to the analysis manager.
  // Get the pointer to the existing analysis manager via the static access method.
  TString outputFileName(fileNameBase);
  outputFileName.Append(".root");

  //===========================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskBF", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //===========================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddTaskBF", "This task requires an input event handler");
    return NULL;
  }
  TString analysisType = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
  if(dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())) analysisType = "MC";

  // to set the analysis type manually
  if(analysisTypeUser != ""){
    analysisType = analysisTypeUser;
    ::Info("AddTaskBF",Form("Analysis Type manually set to %s",analysisType.Data()));
  }

  // for local changed BF configuration
  //gROOT->LoadMacro("./configBalanceFunctionPsiAnalysis.C");
  gROOT->LoadMacro("$ALICE_ROOT/PWGCF/EBYE/macros/configBalanceFunctionPsiAnalysis.C");
  AliBalancePsi *bf  = 0;  // Balance Function object
  AliBalancePsi *bfs = 0;  // shuffled Balance function object
  AliBalancePsi *bfm = 0;  // mixing Balance function object

  //maximum Delta eta range
  Double_t deltaEtaMax=TMath::Abs(etaMax-etaMin);

  if (analysisType=="ESD"){
    bf  = GetBalanceFunctionObject("ESD",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunShuffling) bfs = GetBalanceFunctionObject("ESD",centralityEstimator,centrMin,centrMax,kTRUE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunMixing)    bfm = GetBalanceFunctionObject("ESD",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
  }
  else if (analysisType=="AOD"){
    bf  = GetBalanceFunctionObject("AOD",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunShuffling) bfs = GetBalanceFunctionObject("AOD",centralityEstimator,centrMin,centrMax,kTRUE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunMixing)    bfm = GetBalanceFunctionObject("AOD",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
  }
  else if (analysisType=="MC"){
    bf  = GetBalanceFunctionObject("MC",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunShuffling) bfs = GetBalanceFunctionObject("MC",centralityEstimator,centrMin,centrMax,kTRUE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
    if(gRunMixing)    bfm = GetBalanceFunctionObject("MC",centralityEstimator,centrMin,centrMax,kFALSE,bResonancesCut,bHBTcut,bConversionCut,bMomentumDifferenceCut,fArgEventClass,deltaEtaMax,bVertexBinning);
  }
  else{
    ::Error("AddTaskBF", "analysis type NOT known.");
    return NULL;
  }

  // Create the task, add it to manager and configure it.
  //===========================================================================
  AliAnalysisTaskBFPsi *taskBF = new AliAnalysisTaskBFPsi("TaskBFPsi");

  //Event characteristics scheme
  taskBF->SetEventClass(fArgEventClass);
  if(fArgEventClass == "Multiplicity")
    taskBF->SetMultiplicityRange(centrMin,centrMax);
  else {
    if(analysisType == "MC")
      taskBF->SetImpactParameterRange(centrMin,centrMax);
    else {
    taskBF->SetCentralityPercentileRange(centrMin,centrMax);
    // centrality estimator (default = V0M)
    taskBF->SetCentralityEstimator(centralityEstimator);
    }
  }

  taskBF->SetAnalysisObject(bf);
  if(gRunShuffling) taskBF->SetShufflingObject(bfs);
  if(gRunMixing){
    taskBF->SetMixingObject(bfm);
    taskBF->SetMixingTracks(50000);
    if(gRunMixingWithEventPlane){
      taskBF->SetMixingWithEventPlane(gRunMixingWithEventPlane);
    }
  }

  if(analysisType == "ESD") {
    AliESDtrackCuts *trackCuts = GetTrackCutsObject(ptMin,ptMax,etaMin,etaMax,maxTPCchi2,DCAxy,DCAz,minNClustersTPC);
    taskBF->SetAnalysisCutObject(trackCuts);
    if(kUsePID) {
      if(kUseBayesianPID)
	taskBF->SetUseBayesianPID(gMinAcceptedProbability);
      else if(kUseNSigmaPID)
	taskBF->SetUseNSigmaPID(nSigmaMax);
      taskBF->SetParticleOfInterest(AliAnalysistaskBFPsi::kProton);
      taskBF->SetDetectorUsedForPID(AliAnalysisTaskBFPsi::kTOFpid);
    }
  }
  else if(analysisType == "AOD") {
    // pt and eta cut (pt_min, pt_max, eta_min, eta_max)
    taskBF->SetAODtrackCutBit(AODfilterBit);
    taskBF->SetKinematicsCutsAOD(ptMin,ptMax,etaMin,etaMax);

    // set extra DCA cuts (-1 no extra cut)
    taskBF->SetExtraDCACutsAOD(DCAxy,DCAz);

    // set extra TPC chi2 / nr of clusters cut
    taskBF->SetExtraTPCCutsAOD(maxTPCchi2, minNClustersTPC);

  }
  else if(analysisType == "MC") {
    taskBF->SetKinematicsCutsAOD(ptMin,ptMax,etaMin,etaMax);
  }

  // offline trigger selection (AliVEvent.h)
  // taskBF->UseOfflineTrigger(); // NOT used (selection is done with the AliAnalysisTaskSE::SelectCollisionCandidates())
  // with this only selected events are analyzed (first 2 bins in event QA histogram are the same))
  // documentation in https://twiki.cern.ch/twiki/bin/viewauth/ALICE/PWG1EvSelDocumentation
  if(bCentralTrigger) taskBF->SelectCollisionCandidates(AliVEvent::kMB | AliVEvent::kCentral | AliVEvent::kSemiCentral);
  else                taskBF->SelectCollisionCandidates(AliVEvent::kMB);

  // vertex cut (x,y,z)
  taskBF->SetVertexDiamond(.3,.3,vertexZ);

  //bf->PrintAnalysisSettings();
  mgr->AddTask(taskBF);

  // Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================
  TString outputFileName = AliAnalysisManager::GetCommonFileName();
  outputFileName += ":PWGCFEbyE.outputBalanceFunctionPsiAnalysis";
  AliAnalysisDataContainer *coutQA = mgr->CreateContainer(Form("listQAPsi_%.0f-%.0f_Bit%d_%s",centrMin,centrMax,AODfilterBit,centralityEstimator.Data()), TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());
  AliAnalysisDataContainer *coutBF = mgr->CreateContainer(Form("listBFPsi_%.0f-%.0f_Bit%d_%s",centrMin,centrMax,AODfilterBit,centralityEstimator.Data()), TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());
  if(gRunShuffling) AliAnalysisDataContainer *coutBFS = mgr->CreateContainer(Form("listBFPsiShuffled_%.0f-%.0f_Bit%d_%s",centrMin,centrMax,AODfilterBit,centralityEstimator.Data()), TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());
  if(gRunMixing) AliAnalysisDataContainer *coutBFM = mgr->CreateContainer(Form("listBFPsiMixed_%.0f-%.0f_Bit%d_%s",centrMin,centrMax,AODfilterBit,centralityEstimator.Data()), TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());
  if(kUsePID) AliAnalysisDataContainer *coutQAPID = mgr->CreateContainer(Form("listQAPIDPsi_%.0f-%.0f_Bit%d_%s",centrMin,centrMax,AODfilterBit,centralityEstimator.Data()), TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());

  mgr->ConnectInput(taskBF, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(taskBF, 1, coutQA);
  mgr->ConnectOutput(taskBF, 2, coutBF);
  if(gRunShuffling) mgr->ConnectOutput(taskBF, 3, coutBFS);
  if(gRunMixing) mgr->ConnectOutput(taskBF, 4, coutBFM);
  if(kUsePID && analysisType == "ESD") mgr->ConnectOutput(taskBF, 5, coutQAPID);

  return taskBF;
}
<|endoftext|>


<commit_before>/**
 *  @brief     KiskisAgent.cpp
 *  @class     KiskisAgent.cpp
 *  @details   This is KiskisAgent Software main process.
 *  		   It's main responsibility is that send and receive messages from ActiveMQ broker.
 *  		   It also creates a new process using KAThread Class when the new Execute Request comes.
 *  @author    Emin INAL
 *  @author    Bilal BAL
 *  @version   1.0
 *  @date      Sep 27, 2013
 *  @copyright GNU Public License.
 */

/** \mainpage  Welcome to Project KiskisAgent
 *	\section   KisKisAgent
 * 			   The Kiskis Agent is a simple daemon designed to connect securely to an AMQP server to reliably receive and send messages on queues and topics.
 * 	 	 	   It's purpose is to perform a very simple reduced set of instructions to manage any system administration task.
 * 	 	 	   The agent may run on physical servers, virtual machines or inside Linux Containers.
 */
#include "KACommand.h"
#include "KAResponse.h"
#include "KAUserID.h"
#include "KAResponsePack.h"
#include "KAThread.h"
#include "KALogger.h"
#include "KAConnection.h"
#include "pugixml/pugixml.hpp"
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>

/**
 *  \details   KiskisAgent's settings.xml is read by this function.
 *  		   url: Broker address is fetched. (for instance: url = "failover://(ssl://localhost:61167))
 *  		   connectionOptions: ReconnectDelay and Reconnect feature settings.
 *  		   loglevel: Debugging Loglevel. (0-8)
 */
int getSettings(string & url, string & connectionOptions, string & loglevel)
{
	KALogger DummyLogger;
	DummyLogger.openLogFileWithName("KiskisAgentMain.log");
	DummyLogger.setLogLevel(7);

	pugi::xml_document doc;

	if(doc.load_file("/etc/KiskisAgent/config/settings.xml").status)		//if the settings file does not exist
	{
		return 100;
		exit(1);
	}
	url = doc.child("Settings").child_value("BrokerIP") ;		//reading url
	loglevel = doc.child("Settings").child_value("log_level") ;		//reading loglevel

	url = "failover://(ssl://" + url +":"+  doc.child("Settings").child_value("Port") + ")";		//combine url and port

	connectionOptions = "{reconnect:" + (string)(doc.child("Settings").child_value("reconnect")) + ", reconnect_timeout:" + doc.child("Settings").child_value("reconnect_timeout") +
			", reconnect_interval_max:" + doc.child("Settings").child_value("reconnect_interval_max") + "}";		//combine connectionOptions string

	DummyLogger.closeLogFile();
	return 0;
}
/**
 *  \details   UUID of the KiskisAgent is fetched from statically using this function.
 *  		   Example uuid:"ff28d7c7-54b4-4291-b246-faf3dd493544"
 */
bool getUuid(string& Uuid)
{
	try
	{
		ifstream file("/etc/KiskisAgent/config/uuid.txt");	//opening mac.txt
		getline(file,Uuid);
		file.close();
		if(Uuid.empty())		//if mac is null or not reading successfully
		{
			return false;
		}
		return true;
	}
	catch(const std::exception& error)
	{
		cout << error.what()<< endl;
	}
	return false;
}
/**
 *  \details   threadSend function sends string messages in the Shared Memory buffer to ActiveMQ Broker.
 *  		   This is a thread with working concurrently with main thread.
 *  		   It is main purpose that checking the Shared Memory Buffer in Blocking mode and sending them to Broker
 */
void threadSend(message_queue *mq,KAConnection *connection)
{
	try
	{
		string str;
		unsigned int priority;
		message_queue::size_type recvd_size;
		while(true)
		{
			str.resize(2500);
			mq->receive(&str[0],str.size(),recvd_size,priority);
			connection->sendMessage(str);
			str.clear();
		}
		message_queue::remove("message_queue");
	}
	catch(interprocess_exception &ex)
	{
		message_queue::remove("message_queue");
		std::cout << ex.what() << std::endl;
	}
}
/**
 *  \details   This function is the main thread of KiskisAgent.
 *  		   It sends and receives messages from ActiveMQ broker.
 *  		   It is also responsible from creation new process.
 */
int main(int argc,char *argv[],char *envp[])
{
	string url,connectionOptions,loglevel;
	string Uuid;
	string serveraddress="SERVICE_QUEUE";
	string clientaddress;

	getSettings(url,connectionOptions,loglevel);
	int level;
	stringstream(loglevel) >> level;
	KALogger logMain;
	logMain.openLogFileWithName("KiskisAgentMain.log");
	logMain.setLogLevel(level);

	if(!getUuid(Uuid))
	{						//get UUID of the agent if it exist. if it does not it will be regenerated..
		boost::uuids::random_generator gen;
		boost::uuids::uuid u = gen();

		const std::string tmp = boost::lexical_cast<std::string>(u);
		Uuid = tmp;
		ofstream file("/etc/KiskisAgent/config/uuid.txt");
		file << Uuid;
		file.close();
	}

	activemq::library::ActiveMQCPP::initializeLibrary();
	decaf::lang::System::setProperty("decaf.net.ssl.keyStore","/etc/KiskisAgent/config/client_ks.pem");
	decaf::lang::System::setProperty("decaf.net.ssl.keyStorePassword",	"123456");
	decaf::lang::System::setProperty("decaf.net.ssl.trustStore", "/etc/KiskisAgent/config/client_ts.pem" );

	clientaddress = Uuid;
	KAThread thread;
	KAConnection connection(url,serveraddress,clientaddress);
	KACommand command;
	KAResponsePack response;
	string input;
	string sendout;

	if(! thread.getUserID().checkRootUser())
	{
		//user is not root KiskisAgent Will be closed
		cout << "Main Process User is not root.. KiskisAgent is going to be closed.."<<endl;
		close(STDIN_FILENO);
		close(STDOUT_FILENO);
		close(STDERR_FILENO);

		return 300;
	}

	response.setUuid(Uuid); 	//setting Uuid for response messages.
	if(!connection.openSession())
	{
		return 400;
	}

	sendout = response.createRegistrationMessage(response.getUuid());
	connection.sendMessage(sendout);

	message_queue messageQueue
	(open_or_create              //only create
			,"message_queue"           //name
			,5                       //max message number
			,2500             //max message size
	);
	boost::thread thread1(threadSend,&messageQueue,&connection);

	/* Change the file mode mask */
	umask(0);
	//	For responses the type parameter might have the following values: EXECUTE_RESPONSE, EXECUTE_RESPONSE_DONE, REGISTRATION_REQUEST, HEARTBEAT_RESPONSE, TERMINATE_REQUEST_DONE
	//	For commands the type parameter might have the following values: EXECUTE_REQUEST, REGISTRATION_REQUEST_DONE, HEARTBEAT_REQUEST, TERMINATE_REQUEST
	while(true)
	{
		try
		{
			if(connection.fetchMessage(input)) 	//check and wait if new message comes?
			{
				if(command.deserialize(input))
				{
					if(command.getType()=="REGISTRATION_REQUEST_DONE") //type is registration done
					{
						//agent is registered to server now
					}
					else if(command.getType()=="EXECUTE_REQUEST")	//execution request will be executed in other process.
					{
						KAThread* mypointer = new KAThread;
						mypointer->getLogger().setLogLevel(level);
						mypointer->threadFunction(&messageQueue,&command);
						delete mypointer;
					}
					else if(command.getType()=="HEARTBEAT_REQUEST")
					{
						connection.sendMessage(response.createHeartBeatMessage(Uuid,command.getRequestSequenceNumber()));
					}
					else if(command.getType()=="TERMINATE_REQUEST")
					{
						if(atoi(command.getPid().c_str()))
						{
							kill(atoi(command.getPid().c_str()),SIGKILL);
						}
						else
						{
						}
						connection.sendMessage(response.createTerminateMessage(Uuid,command.getRequestSequenceNumber()));
					}
				}
				else
				{
					connection.sendMessage(response.createResponseMessage(Uuid,"9999999",command.getRequestSequenceNumber(),819,"Failed to Parse Json!!!",""));
				}
			}
		}
		catch(const std::exception& error)
		{
			cout<<error.what()<<endl;
		}
	}
	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);
	logMain.closeLogFile();
	kill(getpid(),SIGKILL);
	activemq::library::ActiveMQCPP::shutdownLibrary();
	return 0;
}
<commit_msg>Process and main logging has been combined(KSKSAGENT-44)<commit_after>/**
 *  @brief     KiskisAgent.cpp
 *  @class     KiskisAgent.cpp
 *  @details   This is KiskisAgent Software main process.
 *  		   It's main responsibility is that send and receive messages from ActiveMQ broker.
 *  		   It also creates a new process using KAThread Class when the new Execute Request comes.
 *  @author    Emin INAL
 *  @author    Bilal BAL
 *  @version   1.0
 *  @date      Sep 27, 2013
 *  @copyright GNU Public License.
 */

/** \mainpage  Welcome to Project KiskisAgent
 *	\section   KisKisAgent
 * 			   The Kiskis Agent is a simple daemon designed to connect securely to an AMQP server to reliably receive and send messages on queues and topics.
 * 	 	 	   It's purpose is to perform a very simple reduced set of instructions to manage any system administration task.
 * 	 	 	   The agent may run on physical servers, virtual machines or inside Linux Containers.
 */
#include "KACommand.h"
#include "KAResponse.h"
#include "KAUserID.h"
#include "KAResponsePack.h"
#include "KAThread.h"
#include "KALogger.h"
#include "KAConnection.h"
#include "pugixml/pugixml.hpp"
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>

/**
 *  \details   KiskisAgent's settings.xml is read by this function.
 *  		   url: Broker address is fetched. (for instance: url = "failover://(ssl://localhost:61167))
 *  		   connectionOptions: ReconnectDelay and Reconnect feature settings.
 *  		   loglevel: Debugging Loglevel. (0-8)
 */
int getSettings(string & url, string & connectionOptions, string & loglevel)
{
	pugi::xml_document doc;

	if(doc.load_file("/etc/KiskisAgent/config/settings.xml").status)		//if the settings file does not exist
	{
		return 100;
		exit(1);
	}
	url = doc.child("Settings").child_value("BrokerIP") ;		//reading url
	loglevel = doc.child("Settings").child_value("log_level") ;		//reading loglevel

//	url = "failover://ssl://" + url +":"+  doc.child("Settings").child_value("Port");		//combine url and port

	url = "ssl://" + url +":"+  doc.child("Settings").child_value("Port");		//combine url and port

	connectionOptions = "{reconnect:" + (string)(doc.child("Settings").child_value("reconnect")) + ", reconnect_timeout:" + doc.child("Settings").child_value("reconnect_timeout") +
			", reconnect_interval_max:" + doc.child("Settings").child_value("reconnect_interval_max") + "}";		//combine connectionOptions string
	return 0;
}
/**
 *  \details   UUID of the KiskisAgent is fetched from statically using this function.
 *  		   Example uuid:"ff28d7c7-54b4-4291-b246-faf3dd493544"
 */
bool getUuid(string& Uuid)
{
	try
	{
		ifstream file("/etc/KiskisAgent/config/uuid.txt");	//opening mac.txt
		getline(file,Uuid);
		file.close();
		if(Uuid.empty())		//if mac is null or not reading successfully
		{
			return false;
		}
		return true;
	}
	catch(const std::exception& error)
	{
		cout << error.what()<< endl;
	}
	return false;
}
/**
 *  \details   threadSend function sends string messages in the Shared Memory buffer to ActiveMQ Broker.
 *  		   This is a thread with working concurrently with main thread.
 *  		   It is main purpose that checking the Shared Memory Buffer in Blocking mode and sending them to Broker
 */
void threadSend(message_queue *mq,KAConnection *connection,KALogger* logMain)
{
	try
	{
		string str;
		unsigned int priority;
		message_queue::size_type recvd_size;
		while(true)
		{
			str.resize(2500);
			mq->receive(&str[0],str.size(),recvd_size,priority);
		//	logMain->writeLog(7,logMain->setLogData("<KiskisAgent>::<threadsend>","New message comes to messagequeue to be sent:",str));
			connection->sendMessage(str);
			str.clear();
		}
		message_queue::remove("message_queue");
	}
	catch(interprocess_exception &ex)
	{
		message_queue::remove("message_queue");
		std::cout << ex.what() << std::endl;
		logMain->writeLog(3,logMain->setLogData("<KiskisAgent>::<threadsend>","New excception Handled:",ex.what()));
	}
}
/**
 *  \details   This function is the main thread of KiskisAgent.
 *  		   It sends and receives messages from ActiveMQ broker.
 *  		   It is also responsible from creation new process.
 */
int main(int argc,char *argv[],char *envp[])
{
	string url,connectionOptions,loglevel;
	string Uuid;
	string serveraddress="SERVICE_QUEUE";
	string clientaddress;
	KAThread thread;
	int level;

	if(! thread.getUserID().checkRootUser())
	{
		//user is not root KiskisAgent Will be closed
		cout << "Main Process User is not root.. KiskisAgent is going to be closed.."<<endl;
		close(STDIN_FILENO);
		close(STDOUT_FILENO);
		close(STDERR_FILENO);
		return 300;
	}
	KALogger logMain;
	logMain.openLogFileWithName("KiskisAgentMain.log");
	logMain.setLogLevel(7);
	logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","KiskisAgent is starting.."));
	logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","Settings.xml is reading.."));

	if(!getSettings(url,connectionOptions,loglevel))
	{

		logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","URL:",url));
		logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","ConnectionOptions:",connectionOptions));
		logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","LogLevel:",loglevel));
		logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","Settings.xml is read successfully.."));
		stringstream(loglevel) >> level;
		logMain.setLogLevel(level);
	}
	else
	{
		logMain.writeLog(3,logMain.setLogData("<KiskisAgent>","Settings.xml cannot be read KiskisAgent is closing.."));
		logMain.closeLogFile();
		return 100;
	}

	if(!getUuid(Uuid))
	{						//get UUID of the agent if it exist. if it does not it will be regenerated..
		boost::uuids::random_generator gen;
		boost::uuids::uuid u = gen();

		const std::string tmp = boost::lexical_cast<std::string>(u);
		Uuid = tmp;
		ofstream file("/etc/KiskisAgent/config/uuid.txt");
		file << Uuid;
		file.close();
		logMain.writeLog(1,logMain.setLogData("<KiskisAgent>","KiskisAgent UUID:",Uuid));
	}

	logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","KiskisAgent UUID:",Uuid));

	activemq::library::ActiveMQCPP::initializeLibrary();
	decaf::lang::System::setProperty("decaf.net.ssl.keyStore","/etc/KiskisAgent/config/client_ks.pem");
	decaf::lang::System::setProperty("decaf.net.ssl.keyStorePassword",	"client");
	decaf::lang::System::setProperty("decaf.net.ssl.trustStore", "/etc/KiskisAgent/config/client_ts.pem" );

	clientaddress = Uuid;
	logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","Connection url:",url));
	logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","Server Address:",serveraddress));
	logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","Cleint Address:",clientaddress));
	KAConnection connection(url,serveraddress,clientaddress);
	logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","Trying to open Connection with ActiveMQ Broker: ",url));
	KACommand command;
	KAResponsePack response;
	string input;
	string sendout;

	response.setUuid(Uuid); 	//setting Uuid for response messages.
	if(!connection.openSession())
	{
		logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","Connection could not be established withActiveMQ Broker: ",url));
		logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","KiskisAgent is closing.."));
		logMain.closeLogFile();
		return 400;
	}
	logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","Connection Successfully opened with ActiveMQ Broker: ",url));
	logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","Registration Message is sending to ActiveMQ Broker.."));

	sendout = response.createRegistrationMessage(response.getUuid());
	logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","Registration Message:",sendout));
	connection.sendMessage(sendout);

	logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","Shared Memory MessageQueue is initializing.."));
	message_queue messageQueue
	(open_or_create              //only create
			,"message_queue"           //name
			,100                       //max message number
			,2500             //max message size
	);
	logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","Sending Thread is starting.."));
	boost::thread thread1(threadSend,&messageQueue,&connection,&logMain);

	/* Change the file mode mask */
	umask(0);
	//	For responses the type parameter might have the following values: EXECUTE_RESPONSE, EXECUTE_RESPONSE_DONE, REGISTRATION_REQUEST, HEARTBEAT_RESPONSE, TERMINATE_REQUEST_DONE
	//	For commands the type parameter might have the following values: EXECUTE_REQUEST, REGISTRATION_REQUEST_DONE, HEARTBEAT_REQUEST, TERMINATE_REQUEST
	while(true)
	{
		try
		{
			if(connection.fetchMessage(input)) 	//check and wait if new message comes?
			{
				if(command.deserialize(input))
				{
		//			logMain.writeLog(6,logMain.setLogData("<KiskisAgent>","New Message is received"));
		//			logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","New Message:",input));
					if(command.getType()=="REGISTRATION_REQUEST_DONE") //type is registration done
					{
						logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","Registration is done.."));
						//agent is registered to server now
					}
					else if(command.getType()=="EXECUTE_REQUEST")	//execution request will be executed in other process.
					{
						logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","Execute operation is starting.."));
						KAThread* mypointer = new KAThread;
						mypointer->getLogger().setLogLevel(level);
						mypointer->threadFunction(&messageQueue,&command);
						delete mypointer;
					}
					else if(command.getType()=="HEARTBEAT_REQUEST")
					{
						logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","Heartbeat message has been taken.."));
						connection.sendMessage(response.createHeartBeatMessage(Uuid,command.getRequestSequenceNumber()));
					}
					else if(command.getType()=="TERMINATE_REQUEST")
					{
						logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","Termination request ID:",command.getPid()));
						if(atoi(command.getPid().c_str()))
						{
							logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","Killing given PID.."));
							kill(atoi(command.getPid().c_str()),SIGKILL);
						}
						else
						{

						}
						connection.sendMessage(response.createTerminateMessage(Uuid,command.getRequestSequenceNumber()));
					}
				}
				else
				{
					logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","Failed at parsing Json String: ",input));
					connection.sendMessage(response.createResponseMessage(Uuid,"9999999",command.getRequestSequenceNumber(),819,"Failed to Parse Json!!!",""));
				}
			}
		}
		catch(const std::exception& error)
		{
			logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","Exception is raised: ",error.what()));
			cout<<error.what()<<endl;
		}
	}
	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);
	logMain.writeLog(7,logMain.setLogData("<KiskisAgent>","KiskisAgent is closing Successfully.."));
	logMain.closeLogFile();
	kill(getpid(),SIGKILL);
	activemq::library::ActiveMQCPP::shutdownLibrary();
	return 0;
}
<|endoftext|>


<commit_before>#include "Halide.h"
#include <cstdlib>
#include <chrono>
#include <fstream>
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include "configure.h"
#include "generated_conv_block.o.h"
#include <tiramisu/utils.h>
using namespace std;

int main(int, char**)
{
    Halide::Buffer<float> input(N+K, N+K, FIn, BATCH_SIZE);
    Halide::Buffer<float> filter(K+1, K+1, FIn, FOut);
    Halide::Buffer<float> bias(FOut);
    Halide::Buffer<float> conv(N, N, FOut, BATCH_SIZE);

    Halide::Buffer<float> filter2(K+1, K+1, FOut, FOut);
    Halide::Buffer<float> bias2(FOut);

    Halide::Buffer<float> conv2_tiramisu(N-K, N-K, FOut, BATCH_SIZE);
    Halide::Buffer<float> maxpool_tiramisu(N-2*K, N-2*K, FOut, BATCH_SIZE);
    Halide::Buffer<int> parameters(5);
    Halide::Buffer<float> negative_slope(1);negative_slope(0) = 1;

    std::vector<std::chrono::duration<double,std::milli>> duration_vector_1;
    std::vector<std::chrono::duration<double,std::milli>> duration_vector_2;

    for (int i=0; i<NB_TESTS; i++)
    {

srand (1);
for (int n = 0; n < BATCH_SIZE; ++n)
	for (int z = 0; z < FIn; ++z)
		for (int y = 0; y < N+K; ++y)
			for (int x = 0; x < N+K; ++x)
			    input(x, y, z, n) = rand()%10;

    for (int z = 0; z < FOut; ++z)
        bias(z) = 0;

     for (int y = 0; y < K+1; ++y)
        for (int x = 0; x < K+1; ++x)
            for (int z = 0; z < FIn; ++z)
		for (int q = 0; q < FOut; ++q)
		    filter(x, y, z, q) = 1;

     for (int z = 0; z < FOut; ++z)
        bias2(z) = 0;

     for (int y = 0; y < K+1; ++y)
        for (int x = 0; x < K+1; ++x)
            for (int z = 0; z < FIn; ++z)
		for (int q = 0; q < FOut; ++q)
		    filter2(x, y, z, q) = 1;

    std::cout << "\t\tBuffers initialized" << std::endl;

    // Initialize parameters[]
    parameters(0) = N;
    parameters(1) = K;
    parameters(2) = FIn;
    parameters(3) = FOut;
    parameters(4) = BATCH_SIZE;

        auto start1 = std::chrono::high_resolution_clock::now();
	conv_block_tiramisu(parameters.raw_buffer(), input.raw_buffer(), filter.raw_buffer(), bias.raw_buffer(), conv.raw_buffer(), filter2.raw_buffer(), bias2.raw_buffer(), conv2_tiramisu.raw_buffer(),maxpool_tiramisu.raw_buffer(),negative_slope.raw_buffer());

std::ofstream resultfile;
  resultfile.open ("/home/radja/Desktop/resultTiramisu.txt");

for (int n = 0; n < BATCH_SIZE; ++n)
	for (int z = 0; z < FOut; ++z)
		for (int y = 0; y < N-2*K; ++y)
			for (int x = 0; x < N-2*K; ++x)	resultfile <<maxpool_tiramisu(x, y, z, n);

  resultfile.close();

	auto end1 = std::chrono::high_resolution_clock::now();
	std::chrono::duration<double,std::milli> duration = end1 - start1;
	duration_vector_2.push_back(duration);
    }

    std::cout << "\t\tTiramisu conv2 duration" << ": " << median(duration_vector_2)/1000 << "; " << std::endl;
    std::cout << "\t\t Result" << ": ";

//   print_buffer(input);

/*for (int n = 0; n < BATCH_SIZE; ++n)
	for (int z = 0; z < FIn; ++z) {
		for (int y = 0; y < N+K; ++y){
			for (int x = 0; x < N+K; ++x)
			    printf("%d ,",(int)input(x, y, z, n) );printf("\n"); } printf("\n");}

//print_buffer(conv);
for (int n = 0; n < BATCH_SIZE; ++n)
	for (int z = 0; z < FOut; ++z) {
		for (int y = 0; y < N; ++y){
			for (int x = 0; x < N; ++x)
			    printf("%d ,",(int)conv(x, y, z, n) );printf("\n"); } printf("\n");}

//  print_buffer(conv2_tiramisu);
for (int n = 0; n < BATCH_SIZE; ++n)
	for (int z = 0; z < FOut; ++z) {
		for (int y = 0; y < N-K; ++y){
			for (int x = 0; x < N-K; ++x)
			    printf("%d ,",(int)conv2_tiramisu(x, y, z, n) );printf("\n"); } printf("\n");}*/

ifstream in("/home/radja/Desktop/resultTiramisu.txt");
ifstream in2("/home/radja/Desktop/result.txt");

    while ((!in.eof()) && (!in2.eof())) {
		string line,line2;
		getline(in,line);
		getline(in2,line2);
        if(line!=line2){ printf("error !!"); break;}
	else {	if ((in.eof()) && (in2.eof()) ) printf("\n\n correct\n\n"); }
    }

    in.close(); in2.close();

    return 0;
}
<commit_msg>Delete wrapper_nn_block.cpp<commit_after><|endoftext|>


<commit_before>#ifndef BLUETOE_LINK_LAYER_CONNECTION_CALLBACKS_HPP
#define BLUETOE_LINK_LAYER_CONNECTION_CALLBACKS_HPP

namespace bluetoe {
namespace link_layer {
    class connection_details;

    namespace details {
        struct connection_callbacks_meta_type {};
    }

    /**
     * @brief provides a type and an instance to call connection related callbacks on.
     *
     * The parameter T have to be a class type with following optional none static member
     * functions:
     *
     * template < typename ConnectionData >
     * void ll_connection_established( const bluetoe::link_layer::connection_details& details, const ConnectionData& connection );
     *
     * template < typename ConnectionData >
     * void ll_connection_changed( const bluetoe::link_layer::connection_details& details, const ConnectionData& connection );
     *
     * template < typename ConnectionData >
     * void ll_connection_closed( const ConnectionData& connection );
     */
    template < typename T, T& Obj >
    struct connection_callbacks {
        /** @cond HIDDEN_SYMBOLS */
        typedef details::connection_callbacks_meta_type meta_type;

        template < class Server >
        class impl {
        public:
            impl()
                : event_type_( none )
                , connection_( nullptr )
            {
            }

            void connection_request( const connection_addresses& addresses )
            {
                addresses_  = addresses;
            }

            // this functions are called from the interrupt handlers of the scheduled radio and just store the informations that
            // are provided.
            template < class Radio >
            void connection_established(
                const connection_details&               details,
                const typename Server::connection_data& connection,
                Radio&                                  r )
            {
                event_type_ = established;
                connection_ = &connection;
                details_    = details;

                r.wake_up();
            }

            template < class Radio >
            void connection_changed( const bluetoe::link_layer::connection_details& details, const typename Server::connection_data& connection, Radio& r )
            {
                event_type_ = changed;
                connection_ = &connection;
                details_    = details;

                r.wake_up();
            }

            template < class Radio >
            void connection_closed( const typename Server::connection_data& connection, Radio& r )
            {
                event_type_ = closed;
                connection_ = &connection;

                r.wake_up();
            }

            void handle_connection_events() {
                if ( event_type_ == established )
                {
                    call_ll_connection_established< T >( Obj, details_, addresses_, *connection_ );
                }
                else if ( event_type_ == changed )
                {
                    call_ll_connection_changed< T >( Obj, details_, *connection_ );
                }
                else if ( event_type_ == closed )
                {
                    call_ll_connection_closed< T >( Obj, *connection_ );
                }

                event_type_ = none;
                connection_ = nullptr;
            }

        private:
            enum {
                none,
                established,
                changed,
                closed
            } event_type_;

            const typename Server::connection_data*     connection_;
            connection_details                          details_;
            connection_addresses                        addresses_;

            template < typename TT >
            auto call_ll_connection_established(
                TT&                                     obj,
                const connection_details&               details,
                const connection_addresses&             addr,
                const typename Server::connection_data& connection )
                    -> decltype(&TT::template ll_connection_established< typename Server::connection_data >)
            {
                obj.ll_connection_established( details, addr, connection );

                return 0;
            }

            template < typename TT >
            auto call_ll_connection_changed( TT& obj, const bluetoe::link_layer::connection_details& details, const typename Server::connection_data& connection )
                -> decltype(&TT::template ll_connection_changed< typename Server::connection_data >)
            {
                obj.ll_connection_changed( details, connection );

                return 0;
            }

            template < typename TT >
            auto call_ll_connection_closed( TT& obj, const typename Server::connection_data& connection )
                -> decltype(&TT::template ll_connection_closed< typename Server::connection_data >)
            {
                obj.ll_connection_closed( connection );

                return 0;
            }

            template < typename TT >
            void call_ll_connection_established( ... )
            {
            }

            template < typename TT >
            void call_ll_connection_changed( ... )
            {
            }

            template < typename TT >
            void call_ll_connection_closed( ... )
            {
            }
        };

        /** @endcond */
    };

    namespace details {
        struct no_connection_callbacks {
            typedef details::connection_callbacks_meta_type meta_type;

            template < class Server >
            struct impl {
                void connection_request( const connection_addresses& addresses ) {}

                template < class Radio >
                void connection_established(
                    const connection_details&               details,
                    const typename Server::connection_data& connection,
                    Radio&                                  r ) {}

                template < class Radio >
                void connection_changed(  const bluetoe::link_layer::connection_details& details, const typename Server::connection_data& connection, Radio& r ) {}

                template < class Radio >
                void connection_closed( const typename Server::connection_data& connection, Radio& r ) {}

                void handle_connection_events() {}
            };
        };
    }

}
}

#endif
<commit_msg>improved documentation<commit_after>#ifndef BLUETOE_LINK_LAYER_CONNECTION_CALLBACKS_HPP
#define BLUETOE_LINK_LAYER_CONNECTION_CALLBACKS_HPP

namespace bluetoe {
namespace link_layer {
    class connection_details;

    namespace details {
        struct connection_callbacks_meta_type {};
    }

    /**
     * @brief provides a type and an instance to call connection related callbacks on.
     *
     * The parameter T have to be a class type with following optional none static member
     * functions:
     *
     * template < typename ConnectionData >
     * void ll_connection_established(
     *          const bluetoe::link_layer::connection_details&   details,
     *          const bluetoe::link_layer::connection_addresses& addresses,
     *          const ConnectionData&                            connection );
     *
     * template < typename ConnectionData >
     * void ll_connection_changed(
     *          const bluetoe::link_layer::connection_details&  details,
     *          const ConnectionData&                           connection );
     *
     * template < typename ConnectionData >
     * void ll_connection_closed( const ConnectionData& connection );
     */
    template < typename T, T& Obj >
    struct connection_callbacks {
        /** @cond HIDDEN_SYMBOLS */
        typedef details::connection_callbacks_meta_type meta_type;

        template < class Server >
        class impl {
        public:
            impl()
                : event_type_( none )
                , connection_( nullptr )
            {
            }

            void connection_request( const connection_addresses& addresses )
            {
                addresses_  = addresses;
            }

            // this functions are called from the interrupt handlers of the scheduled radio and just store the informations that
            // are provided.
            template < class Radio >
            void connection_established(
                const connection_details&               details,
                const typename Server::connection_data& connection,
                Radio&                                  r )
            {
                event_type_ = established;
                connection_ = &connection;
                details_    = details;

                r.wake_up();
            }

            template < class Radio >
            void connection_changed( const bluetoe::link_layer::connection_details& details, const typename Server::connection_data& connection, Radio& r )
            {
                event_type_ = changed;
                connection_ = &connection;
                details_    = details;

                r.wake_up();
            }

            template < class Radio >
            void connection_closed( const typename Server::connection_data& connection, Radio& r )
            {
                event_type_ = closed;
                connection_ = &connection;

                r.wake_up();
            }

            void handle_connection_events() {
                if ( event_type_ == established )
                {
                    call_ll_connection_established< T >( Obj, details_, addresses_, *connection_ );
                }
                else if ( event_type_ == changed )
                {
                    call_ll_connection_changed< T >( Obj, details_, *connection_ );
                }
                else if ( event_type_ == closed )
                {
                    call_ll_connection_closed< T >( Obj, *connection_ );
                }

                event_type_ = none;
                connection_ = nullptr;
            }

        private:
            enum {
                none,
                established,
                changed,
                closed
            } event_type_;

            const typename Server::connection_data*     connection_;
            connection_details                          details_;
            connection_addresses                        addresses_;

            template < typename TT >
            auto call_ll_connection_established(
                TT&                                     obj,
                const connection_details&               details,
                const connection_addresses&             addr,
                const typename Server::connection_data& connection )
                    -> decltype(&TT::template ll_connection_established< typename Server::connection_data >)
            {
                obj.ll_connection_established( details, addr, connection );

                return 0;
            }

            template < typename TT >
            auto call_ll_connection_changed( TT& obj, const bluetoe::link_layer::connection_details& details, const typename Server::connection_data& connection )
                -> decltype(&TT::template ll_connection_changed< typename Server::connection_data >)
            {
                obj.ll_connection_changed( details, connection );

                return 0;
            }

            template < typename TT >
            auto call_ll_connection_closed( TT& obj, const typename Server::connection_data& connection )
                -> decltype(&TT::template ll_connection_closed< typename Server::connection_data >)
            {
                obj.ll_connection_closed( connection );

                return 0;
            }

            template < typename TT >
            void call_ll_connection_established( ... )
            {
            }

            template < typename TT >
            void call_ll_connection_changed( ... )
            {
            }

            template < typename TT >
            void call_ll_connection_closed( ... )
            {
            }
        };

        /** @endcond */
    };

    namespace details {
        struct no_connection_callbacks {
            typedef details::connection_callbacks_meta_type meta_type;

            template < class Server >
            struct impl {
                void connection_request( const connection_addresses& addresses ) {}

                template < class Radio >
                void connection_established(
                    const connection_details&               details,
                    const typename Server::connection_data& connection,
                    Radio&                                  r ) {}

                template < class Radio >
                void connection_changed(  const bluetoe::link_layer::connection_details& details, const typename Server::connection_data& connection, Radio& r ) {}

                template < class Radio >
                void connection_closed( const typename Server::connection_data& connection, Radio& r ) {}

                void handle_connection_events() {}
            };
        };
    }

}
}

#endif
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_FUNCTIONALS_INTERFACES_HH
#define DUNE_GDT_FUNCTIONALS_INTERFACES_HH

#include <dune/stuff/common/crtp.hh>

#include <dune/gdt/spaces/interface.hh>
#include <dune/gdt/discretefunction/default.hh>

namespace Dune {
namespace GDT {

template< class Traits >
class FunctionalInterface
  : public Stuff::CRTPInterface< FunctionalInterface< Traits >, Traits >
{
  typedef typename Traits::derived_type derived_type;
public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::ScalarType   ScalarType;

  template< class SourceType >
  ScalarType apply(const SourceType& source) const
  {
    CHECK_CRTP(this->as_imp().apply(source));
    return this->as_imp().apply(source);
  } // apply(...)
}; // class FunctionalInterface

//! \note derive from FunctionalInterface
template< class Traits >
class AssemblableFunctionalInterface
  : protected Stuff::CRTPInterface< AssemblableFunctionalInterface< Traits >, Traits >
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::SpaceType    SpaceType;
  typedef typename Traits::VectorType   VectorType;
  typedef typename Traits::ScalarType   ScalarType;

private:
  static_assert(std::is_base_of< SpaceInterface< typename SpaceType::Traits,
                                                 SpaceType::dimDomain,
                                                 SpaceType::dimRange,
                                                 SpaceType::dimRangeCols >,
                                 SpaceType >::value,
                "SpaceType has to be derived from SpaceInterface!");
  static_assert(std::is_base_of
                < Stuff::LA::VectorInterface< typename VectorType::Traits, ScalarType >,
                  VectorType >::value,
                "VectorType has to be derived from Stuff::LA::VectorInterface!");

public:
  const GridViewType& grid_view() const
  {
    CHECK_CRTP(this->as_imp().grid_view());
    return this->as_imp().grid_view();
  }

  const SpaceType& space() const
  {
    CHECK_CRTP(this->as_imp().space());
    return this->as_imp().space();
  }

  void assemble()
  {
    CHECK_AND_CALL_CRTP(this->as_imp().assemble());
  }

  VectorType& vector()
  {
    CHECK_CRTP(this->as_imp().vector());
    return this->as_imp().vector();
  }

  const VectorType& vector() const
  {
    CHECK_CRTP(this->as_imp().vector());
    return this->as_imp().vector();
  }

  template< class S >
  ScalarType apply(const Stuff::LA::VectorInterface< S, ScalarType >& source) const
  {
    typedef typename S::derived_type SourceType;
    assemble();
    return vector().dot(static_cast< SourceType& >(source));
  }

  template< class S >
  ScalarType apply(const ConstDiscreteFunction< SpaceType, S >& source) const
  {
    assemble();
    assert(source.vector().size() == vector().size());
    return apply(source.vector());
  }
}; // class AssemblableFunctionalInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_FUNCTIONALS_INTERFACES_HH
<commit_msg>[functionals.interfaces] modernize static checks<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_FUNCTIONALS_INTERFACES_HH
#define DUNE_GDT_FUNCTIONALS_INTERFACES_HH

#include <dune/stuff/common/crtp.hh>

#include <dune/gdt/spaces/interface.hh>
#include <dune/gdt/discretefunction/default.hh>

namespace Dune {
namespace GDT {

template< class Traits >
class FunctionalInterface
  : public Stuff::CRTPInterface< FunctionalInterface< Traits >, Traits >
{
  typedef typename Traits::derived_type derived_type;
public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::ScalarType   ScalarType;

  template< class SourceType >
  ScalarType apply(const SourceType& source) const
  {
    CHECK_CRTP(this->as_imp().apply(source));
    return this->as_imp().apply(source);
  } // apply(...)
}; // class FunctionalInterface

//! \note derive from FunctionalInterface
template< class Traits >
class AssemblableFunctionalInterface
  : protected Stuff::CRTPInterface< AssemblableFunctionalInterface< Traits >, Traits >
{
public:
  typedef typename Traits::derived_type derived_type;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::SpaceType    SpaceType;
  typedef typename Traits::VectorType   VectorType;
  typedef typename Traits::ScalarType   ScalarType;

private:
  static_assert(is_space< SpaceType >::value, "SpaceType has to be derived from SpaceInterface!");
  static_assert(Stuff::LA::is_vector< VectorType >::value,
                "VectorType has to be derived from Stuff::LA::VectorInterface!");

public:
  const GridViewType& grid_view() const
  {
    CHECK_CRTP(this->as_imp().grid_view());
    return this->as_imp().grid_view();
  }

  const SpaceType& space() const
  {
    CHECK_CRTP(this->as_imp().space());
    return this->as_imp().space();
  }

  void assemble()
  {
    CHECK_AND_CALL_CRTP(this->as_imp().assemble());
  }

  VectorType& vector()
  {
    CHECK_CRTP(this->as_imp().vector());
    return this->as_imp().vector();
  }

  const VectorType& vector() const
  {
    CHECK_CRTP(this->as_imp().vector());
    return this->as_imp().vector();
  }

  template< class S >
  ScalarType apply(const Stuff::LA::VectorInterface< S, ScalarType >& source) const
  {
    typedef typename S::derived_type SourceType;
    assemble();
    return vector().dot(static_cast< SourceType& >(source));
  }

  template< class S >
  ScalarType apply(const ConstDiscreteFunction< SpaceType, S >& source) const
  {
    assemble();
    assert(source.vector().size() == vector().size());
    return apply(source.vector());
  }
}; // class AssemblableFunctionalInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_FUNCTIONALS_INTERFACES_HH
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2011 - 2017)
//   Rene Milk       (2014, 2016 - 2018)
//   Tobias Leibner  (2014, 2016 - 2017)

#ifndef DUNE_GDT_LOCAL_DISCRETEFUNCTION_HH
#define DUNE_GDT_LOCAL_DISCRETEFUNCTION_HH

#include <dune/xt/la/container/vector-interface.hh>
#include <dune/xt/grid/type_traits.hh>
#include <dune/xt/functions/interfaces/grid-function.hh>

#include <dune/gdt/discretefunction/dof-vector.hh>
#include <dune/gdt/exceptions.hh>
#include <dune/gdt/spaces/interface.hh>

namespace Dune {
namespace GDT {

template <class Vector, class GridView, size_t range_dim = 1, size_t range_dim_cols = 1, class RangeField = double>
class ConstLocalDiscreteFunction
    : public XT::Functions::
          ElementFunctionInterface<XT::Grid::extract_entity_t<GridView>, range_dim, range_dim_cols, RangeField>
{
  // No need to check the rest, is done in SpaceInterface.
  static_assert(XT::LA::is_vector<Vector>::value, "");
  static_assert(range_dim_cols == 1, "The matrix-valued case requires updates to evaluate/jacobian/derivative!");

  using ThisType = ConstLocalDiscreteFunction<Vector, GridView, range_dim, range_dim_cols, RangeField>;
  using BaseType = XT::Functions::
      ElementFunctionInterface<XT::Grid::extract_entity_t<GridView>, range_dim, range_dim_cols, RangeField>;

public:
  using SpaceType = SpaceInterface<GridView, range_dim, range_dim_cols, RangeField>;
  using ConstDofVectorType = ConstDofVector<Vector, GridView>;
  using ConstLocalDofVectorType = typename ConstDofVectorType::ConstLocalDofVectorType;
  using LocalBasisType = typename SpaceType::GlobalBasisType::LocalizedBasisType;

  using typename BaseType::ElementType;
  using typename BaseType::DomainType;
  using typename BaseType::RangeSelector;
  using typename BaseType::DerivativeRangeSelector;
  using typename BaseType::RangeType;
  using typename BaseType::DerivativeRangeType;
  using typename BaseType::SingleDerivativeRangeType;
  using typename BaseType::RangeReturnType;
  using typename BaseType::DerivativeRangeReturnType;
  using typename BaseType::SingleDerivativeRangeReturnType;
  using typename BaseType::DynamicRangeType;
  using typename BaseType::DynamicDerivativeRangeType;
  using BaseType::d;
  using BaseType::r;
  using BaseType::rC;
  using typename BaseType::R;

  ConstLocalDiscreteFunction(const SpaceType& spc, const ConstDofVectorType& dof_vector)
    : BaseType()
    , space_(spc)
    , dof_vector_(dof_vector.localize())
    , basis_(space_.basis().localize())
    , basis_values_(space_.mapper().max_local_size())
    , dynamic_basis_values_(space_.mapper().max_local_size())
    , basis_derivatives_(space_.mapper().max_local_size())
    , dynamic_basis_derivatives_(space_.mapper().max_local_size())
  {
  }

protected:
  void post_bind(const ElementType& ent) override
  {
    basis_->bind(ent);
    dof_vector_.bind(ent);
  }

public:
  int order(const XT::Common::Parameter& /*param*/ = {}) const override final
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    return basis_->order();
  }

  const SpaceType& space() const
  {
    return space_;
  }

  const LocalBasisType& basis() const
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    return basis_;
  }

  const ConstLocalDofVectorType& dofs() const
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    return dof_vector_;
  }

  using BaseType::evaluate;
  using BaseType::jacobian;
  using BaseType::derivative;

  /**
    * \name ``These methods are required by XT::Functions::GridFunctionInterface.''
    * \{
    **/

  RangeReturnType evaluate(const DomainType& point_in_reference_element,
                           const XT::Common::Parameter& param = {}) const override final
  {
    DUNE_THROW_IF(!basis_, Exceptions::not_bound_to_an_element_yet, "you need to call bind() first!");
    RangeReturnType result(0);
    if (space_.type() == GDT::SpaceType::finite_volume) {
      for (size_t ii = 0; ii < r; ++ii)
        result[ii] = dof_vector_[ii];
    } else {
      basis_->evaluate(point_in_reference_element, basis_values_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result.axpy(dof_vector_[ii], basis_values_[ii]);
    }
    return result;
  } // ... evaluate(...)

  DerivativeRangeReturnType jacobian(const DomainType& point_in_reference_element,
                                     const XT::Common::Parameter& param = {}) const override final
  {
    DUNE_THROW_IF(!basis_, Exceptions::not_bound_to_an_element_yet, "you need to call bind() first!");
    DerivativeRangeReturnType result(0);
    if (space_.type() == GDT::SpaceType::finite_volume) {
      return result;
    } else {
      basis_->jacobians(point_in_reference_element, basis_derivatives_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result.axpy(dof_vector_[ii], basis_derivatives_[ii]);
    }
    return result;
  } // ... jacobian(...)

  DerivativeRangeReturnType derivative(const std::array<size_t, d>& alpha,
                                       const DomainType& point_in_reference_element,
                                       const XT::Common::Parameter& /*param*/ = {}) const override final
  {
    DUNE_THROW_IF(!basis_, Exceptions::not_bound_to_an_element_yet, "you need to call bind() first!");
    DerivativeRangeReturnType result(0);
    if (space_.type() == GDT::SpaceType::finite_volume) {
      for (size_t jj = 0; jj < d; ++jj)
        if (alpha[jj] == 0)
          for (size_t ii = 0; ii < r; ++ii)
            result[ii][jj] = dof_vector_[ii];
      return result;
    } else {
      DUNE_THROW(Exceptions::discrete_function_error,
                 "arbitrary derivatives are not supported by the local finite elements!\n\n"
                     << "alpha = "
                     << alpha
                     << "\n"
                     << "point_in_reference_element = "
                     << point_in_reference_element);
    }
    return result;
  } // ... derivative(...)

  /**
    * \}
    * \name ``These methods are default implemented in XT::Functions::GridFunctionInterface and are overridden
    *         for improved performance.''
    * \{
    **/

  void evaluate(const DomainType& point_in_reference_element,
                DynamicRangeType& result,
                const XT::Common::Parameter& param = {}) const override final
  {
    RangeSelector::ensure_size(result);
    result *= 0;
    if (space_.type() == GDT::SpaceType::finite_volume) {
      for (size_t ii = 0; ii < r; ++ii)
        result[ii] = dof_vector_[ii];
    } else {
      basis_->evaluate(point_in_reference_element, dynamic_basis_values_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result.axpy(dof_vector_[ii], dynamic_basis_values_[ii]);
    }
  } // ... evaluate(...)

  void jacobian(const DomainType& point_in_reference_element,
                DynamicDerivativeRangeType& result,
                const XT::Common::Parameter& param = {}) const override final
  {
    DerivativeRangeSelector::ensure_size(result);
    result *= 0;
    if (space_.type() == GDT::SpaceType::finite_volume) {
      return;
    } else {
      basis_->jacobians(point_in_reference_element, dynamic_basis_derivatives_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result.axpy(dof_vector_[ii], dynamic_basis_derivatives_[ii]);
    }
  } // ... jacobian(...)

  void derivative(const std::array<size_t, d>& alpha,
                  const DomainType& point_in_reference_element,
                  DynamicDerivativeRangeType& result,
                  const XT::Common::Parameter& /*param*/ = {}) const override final
  {
    DerivativeRangeSelector::ensure_size(result);
    result *= 0;
    if (space_.type() == GDT::SpaceType::finite_volume) {
      for (size_t jj = 0; jj < d; ++jj)
        if (alpha[jj] == 0)
          for (size_t ii = 0; ii < r; ++ii)
            result[ii][jj] = dof_vector_[ii];
    } else {
      DUNE_THROW(Exceptions::discrete_function_error,
                 "arbitrary derivatives are not supported by the local finite elements!\n\n"
                     << "alpha = "
                     << alpha
                     << "\n"
                     << "point_in_reference_element = "
                     << point_in_reference_element);
    }
  } // ... derivative(...)

  /**
    * \}
    * \name ``These methods (used to access an individual range dimension) are default implemented in
    *         XT::Functions::GridFunctionInterface and are implemented for improved performance.''
    * \{
    **/

  R evaluate(const DomainType& point_in_reference_element,
             const size_t row,
             const size_t col = 0,
             const XT::Common::Parameter& param = {}) const override final
  {
    this->assert_correct_dims(row, col, "evaluate");
    if (space_.type() == GDT::SpaceType::finite_volume) {
      return dof_vector_[row];
    } else {
      R result(0);
      basis_->evaluate(point_in_reference_element, basis_values_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result += dof_vector_[ii] * basis_values_[ii][row];
      return result;
    }
  } // ... evaluate(...)

  SingleDerivativeRangeReturnType jacobian(const DomainType& point_in_reference_element,
                                           const size_t row,
                                           const size_t col = 0,
                                           const XT::Common::Parameter& param = {}) const override final
  {
    this->assert_correct_dims(row, col, "jacobian");
    if (space_.type() == GDT::SpaceType::finite_volume) {
      return 0;
    } else {
      SingleDerivativeRangeReturnType result(0);
      basis_->jacobians(point_in_reference_element, basis_derivatives_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result.axpy(dof_vector_[ii], basis_derivatives_[ii][row]);
      return result;
    }
  } // ... jacobian(...)

  /// \}

private:
  const SpaceType& space_;
  ConstLocalDofVectorType dof_vector_;
  std::unique_ptr<LocalBasisType> basis_;
  mutable std::vector<RangeType> basis_values_;
  mutable std::vector<DynamicRangeType> dynamic_basis_values_;
  mutable std::vector<DerivativeRangeType> basis_derivatives_;
  mutable std::vector<DynamicDerivativeRangeType> dynamic_basis_derivatives_;
}; // class ConstLocalDiscreteFunction

template <class V, class GV, size_t r = 1, size_t rC = 1, class R = double>
class LocalDiscreteFunction : public ConstLocalDiscreteFunction<V, GV, r, rC, R>
{
  using ThisType = LocalDiscreteFunction<V, GV, r, rC, R>;
  using BaseType = ConstLocalDiscreteFunction<V, GV, r, rC, R>;

public:
  using typename BaseType::SpaceType;
  using typename BaseType::ElementType;

  using DofVectorType = DofVector<V, GV>;
  using LocalDofVectorType = typename DofVectorType::LocalDofVectorType;

  LocalDiscreteFunction(const SpaceType& spc, DofVectorType& dof_vector)
    : BaseType(spc, dof_vector)
    , dof_vector_(dof_vector.localize())
    , bound_(false)
  {
  }

  LocalDiscreteFunction(const SpaceType& spc, DofVectorType& dof_vector, const ElementType& ent)
    : BaseType(spc, dof_vector, ent)
    , dof_vector_(dof_vector.localize(ent))
    , bound_(true)
  {
  }

protected:
  void post_bind(const ElementType& ent) override
  {
    BaseType::bind(ent);
    dof_vector_.bind(ent);
    bound_ = true;
  }

public:
  LocalDofVectorType& dofs()
  {
    DUNE_THROW_IF(!bound_, Exceptions::not_bound_to_an_element_yet, "you need to call bind() first!");
    return dof_vector_;
  }

private:
  LocalDofVectorType dof_vector_;
  bool bound_;
}; // class LocalDiscreteFunction

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_LOCAL_DISCRETEFUNCTION_HH
<commit_msg>[local.discretefunction] some updates<commit_after>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2011 - 2017)
//   Rene Milk       (2014, 2016 - 2018)
//   Tobias Leibner  (2014, 2016 - 2017)

#ifndef DUNE_GDT_LOCAL_DISCRETEFUNCTION_HH
#define DUNE_GDT_LOCAL_DISCRETEFUNCTION_HH

#include <dune/xt/la/container/vector-interface.hh>
#include <dune/xt/grid/type_traits.hh>
#include <dune/xt/functions/interfaces/grid-function.hh>

#include <dune/gdt/discretefunction/dof-vector.hh>
#include <dune/gdt/exceptions.hh>
#include <dune/gdt/spaces/interface.hh>

namespace Dune {
namespace GDT {

template <class Vector, class GridView, size_t range_dim = 1, size_t range_dim_cols = 1, class RangeField = double>
class ConstLocalDiscreteFunction
    : public XT::Functions::
          ElementFunctionInterface<XT::Grid::extract_entity_t<GridView>, range_dim, range_dim_cols, RangeField>
{
  // No need to check the rest, is done in SpaceInterface.
  static_assert(XT::LA::is_vector<Vector>::value, "");
  static_assert(range_dim_cols == 1, "The matrix-valued case requires updates to evaluate/jacobian/derivative!");

  using ThisType = ConstLocalDiscreteFunction<Vector, GridView, range_dim, range_dim_cols, RangeField>;
  using BaseType = XT::Functions::
      ElementFunctionInterface<XT::Grid::extract_entity_t<GridView>, range_dim, range_dim_cols, RangeField>;

public:
  using SpaceType = SpaceInterface<GridView, range_dim, range_dim_cols, RangeField>;
  using ConstDofVectorType = ConstDofVector<Vector, GridView>;
  using ConstLocalDofVectorType = typename ConstDofVectorType::ConstLocalDofVectorType;
  using LocalBasisType = typename SpaceType::GlobalBasisType::LocalizedBasisType;

  using typename BaseType::ElementType;
  using typename BaseType::DomainType;
  using typename BaseType::RangeSelector;
  using typename BaseType::DerivativeRangeSelector;
  using typename BaseType::RangeType;
  using typename BaseType::DerivativeRangeType;
  using typename BaseType::SingleDerivativeRangeType;
  using typename BaseType::RangeReturnType;
  using typename BaseType::DerivativeRangeReturnType;
  using typename BaseType::SingleDerivativeRangeReturnType;
  using typename BaseType::DynamicRangeType;
  using typename BaseType::DynamicDerivativeRangeType;
  using BaseType::d;
  using BaseType::r;
  using BaseType::rC;
  using typename BaseType::R;

  ConstLocalDiscreteFunction(const SpaceType& spc, const ConstDofVectorType& dof_vector)
    : BaseType()
    , space_(spc)
    , dof_vector_(dof_vector.localize())
    , basis_(space_.basis().localize())
    , basis_values_(space_.mapper().max_local_size())
    , dynamic_basis_values_(space_.mapper().max_local_size())
    , basis_derivatives_(space_.mapper().max_local_size())
    , dynamic_basis_derivatives_(space_.mapper().max_local_size())
  {
  }

protected:
  void post_bind(const ElementType& ent) override
  {
    basis_->bind(ent);
    dof_vector_.bind(ent);
  }

public:
  int order(const XT::Common::Parameter& /*param*/ = {}) const override final
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    return basis_->order();
  }

  const SpaceType& space() const
  {
    return space_;
  }

  const LocalBasisType& basis() const
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    return *basis_;
  }

  const ConstLocalDofVectorType& dofs() const
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    return dof_vector_;
  }

  using BaseType::evaluate;
  using BaseType::jacobian;
  using BaseType::derivative;

  /**
    * \name ``These methods are required by XT::Functions::GridFunctionInterface.''
    * \{
    **/

  RangeReturnType evaluate(const DomainType& point_in_reference_element,
                           const XT::Common::Parameter& param = {}) const override final
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    RangeReturnType result(0);
    if (space_.type() == GDT::SpaceType::finite_volume) {
      for (size_t ii = 0; ii < r; ++ii)
        result[ii] = dof_vector_[ii];
    } else {
      basis_->evaluate(point_in_reference_element, basis_values_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result.axpy(dof_vector_[ii], basis_values_[ii]);
    }
    return result;
  } // ... evaluate(...)

  DerivativeRangeReturnType jacobian(const DomainType& point_in_reference_element,
                                     const XT::Common::Parameter& param = {}) const override final
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    DerivativeRangeReturnType result(0);
    if (space_.type() == GDT::SpaceType::finite_volume) {
      return result;
    } else {
      basis_->jacobians(point_in_reference_element, basis_derivatives_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result.axpy(dof_vector_[ii], basis_derivatives_[ii]);
    }
    return result;
  } // ... jacobian(...)

  DerivativeRangeReturnType derivative(const std::array<size_t, d>& alpha,
                                       const DomainType& point_in_reference_element,
                                       const XT::Common::Parameter& /*param*/ = {}) const override final
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    DUNE_THROW_IF(space_.type() != GDT::SpaceType::finite_volume,
                  Exceptions::discrete_function_error,
                  "arbitrary derivatives are not supported by the local finite elements!\n\n"
                      << "alpha = "
                      << alpha
                      << "\n"
                      << "point_in_reference_element = "
                      << point_in_reference_element);
    DerivativeRangeReturnType result(0);
    for (size_t jj = 0; jj < d; ++jj) {
      if (alpha[jj] == 0) {
        for (size_t ii = 0; ii < r; ++ii)
          result[ii][jj] = dof_vector_[ii];
      } else
        DUNE_THROW(Exceptions::discrete_function_error,
                   "arbitrary derivatives are not supported by the local finite elements!\n\n"
                       << "alpha = "
                       << alpha
                       << "\n"
                       << "point_in_reference_element = "
                       << point_in_reference_element);
    }
    return result;
  } // ... derivative(...)

  /**
    * \}
    * \name ``These methods are default implemented in XT::Functions::GridFunctionInterface and are overridden
    *         for improved performance.''
    * \{
    **/

  void evaluate(const DomainType& point_in_reference_element,
                DynamicRangeType& result,
                const XT::Common::Parameter& param = {}) const override final
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    RangeSelector::ensure_size(result);
    result *= 0;
    if (space_.type() == GDT::SpaceType::finite_volume) {
      for (size_t ii = 0; ii < r; ++ii)
        result[ii] = dof_vector_[ii];
    } else {
      basis_->evaluate(point_in_reference_element, dynamic_basis_values_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result.axpy(dof_vector_[ii], dynamic_basis_values_[ii]);
    }
  } // ... evaluate(...)

  void jacobian(const DomainType& point_in_reference_element,
                DynamicDerivativeRangeType& result,
                const XT::Common::Parameter& param = {}) const override final
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    DerivativeRangeSelector::ensure_size(result);
    result *= 0;
    if (space_.type() == GDT::SpaceType::finite_volume) {
      return;
    } else {
      basis_->jacobians(point_in_reference_element, dynamic_basis_derivatives_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result.axpy(dof_vector_[ii], dynamic_basis_derivatives_[ii]);
    }
  } // ... jacobian(...)

  void derivative(const std::array<size_t, d>& alpha,
                  const DomainType& point_in_reference_element,
                  DynamicDerivativeRangeType& result,
                  const XT::Common::Parameter& /*param*/ = {}) const override final
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    DUNE_THROW_IF(space_.type() != GDT::SpaceType::finite_volume,
                  Exceptions::discrete_function_error,
                  "arbitrary derivatives are not supported by the local finite elements!\n\n"
                      << "alpha = "
                      << alpha
                      << "\n"
                      << "point_in_reference_element = "
                      << point_in_reference_element);
    DerivativeRangeSelector::ensure_size(result);
    result *= 0;
    for (size_t jj = 0; jj < d; ++jj) {
      if (alpha[jj] == 0) {
        for (size_t ii = 0; ii < r; ++ii)
          result[ii][jj] = dof_vector_[ii];
      } else
        DUNE_THROW(Exceptions::discrete_function_error,
                   "arbitrary derivatives are not supported by the local finite elements!\n\n"
                       << "alpha = "
                       << alpha
                       << "\n"
                       << "point_in_reference_element = "
                       << point_in_reference_element);
    }
  } // ... derivative(...)

  /**
    * \}
    * \name ``These methods (used to access an individual range dimension) are default implemented in
    *         XT::Functions::GridFunctionInterface and are implemented for improved performance.''
    * \{
    **/

  R evaluate(const DomainType& point_in_reference_element,
             const size_t row,
             const size_t col = 0,
             const XT::Common::Parameter& param = {}) const override final
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    this->assert_correct_dims(row, col, "evaluate");
    if (space_.type() == GDT::SpaceType::finite_volume) {
      return dof_vector_[row];
    } else {
      R result(0);
      basis_->evaluate(point_in_reference_element, basis_values_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result += dof_vector_[ii] * basis_values_[ii][row];
      return result;
    }
  } // ... evaluate(...)

  SingleDerivativeRangeReturnType jacobian(const DomainType& point_in_reference_element,
                                           const size_t row,
                                           const size_t col = 0,
                                           const XT::Common::Parameter& param = {}) const override final
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    this->assert_correct_dims(row, col, "jacobian");
    if (space_.type() == GDT::SpaceType::finite_volume) {
      return 0;
    } else {
      SingleDerivativeRangeReturnType result(0);
      basis_->jacobians(point_in_reference_element, basis_derivatives_, param);
      for (size_t ii = 0; ii < basis_->size(); ++ii)
        result.axpy(dof_vector_[ii], basis_derivatives_[ii][row]);
      return result;
    }
  } // ... jacobian(...)

  /// \}

private:
  const SpaceType& space_;
  ConstLocalDofVectorType dof_vector_;
  std::unique_ptr<LocalBasisType> basis_;
  mutable std::vector<RangeType> basis_values_;
  mutable std::vector<DynamicRangeType> dynamic_basis_values_;
  mutable std::vector<DerivativeRangeType> basis_derivatives_;
  mutable std::vector<DynamicDerivativeRangeType> dynamic_basis_derivatives_;
}; // class ConstLocalDiscreteFunction

template <class V, class GV, size_t r = 1, size_t rC = 1, class R = double>
class LocalDiscreteFunction : public ConstLocalDiscreteFunction<V, GV, r, rC, R>
{
  using ThisType = LocalDiscreteFunction<V, GV, r, rC, R>;
  using BaseType = ConstLocalDiscreteFunction<V, GV, r, rC, R>;

public:
  using typename BaseType::SpaceType;
  using typename BaseType::ElementType;

  using DofVectorType = DofVector<V, GV>;
  using LocalDofVectorType = typename DofVectorType::LocalDofVectorType;

  LocalDiscreteFunction(const SpaceType& spc, DofVectorType& dof_vector)
    : BaseType(spc, dof_vector)
    , dof_vector_(dof_vector.localize())
  {
  }

  LocalDiscreteFunction(const SpaceType& spc, DofVectorType& dof_vector, const ElementType& ent)
    : BaseType(spc, dof_vector, ent)
    , dof_vector_(dof_vector.localize(ent))
  {
  }

protected:
  void post_bind(const ElementType& ent) override final
  {
    BaseType::bind(ent);
    dof_vector_.bind(ent);
  }

public:
  LocalDofVectorType& dofs()
  {
    DUNE_THROW_IF(!this->is_bound_, Exceptions::not_bound_to_an_element_yet, "");
    return dof_vector_;
  }

private:
  LocalDofVectorType dof_vector_;
}; // class LocalDiscreteFunction

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_LOCAL_DISCRETEFUNCTION_HH
<|endoftext|>