<commit_before>/****************************************************************************
**
** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Script Generator project on Qt Labs.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "shellheadergenerator.h"
#include "fileout.h"

#include <QtCore/QDir>

#include <qdebug.h>

QString ShellHeaderGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const
{
  return QString("PythonQtWrapper_%1.h").arg(meta_class->name());
}

void ShellHeaderGenerator::writeFieldAccessors(QTextStream &s, const AbstractMetaField *field)
{
  const AbstractMetaFunction *setter = field->setter();
  const AbstractMetaFunction *getter = field->getter();

  // static fields are not supported (yet?)
  if (setter->isStatic()) return;

  // Uuid data4 did not work (TODO: move to typesystem...(
  if (field->enclosingClass()->name()=="QUuid" &&  setter->name()=="data4") return;
  if (field->enclosingClass()->name()=="QIPv6Address") return;

  if (!field->type()->isConstant()) {
    writeFunctionSignature(s, setter, 0, QString(),
                           Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | ShowStatic | UnderscoreSpaces));
    s << "{ theWrappedObject->" << field->name() << " = " << setter->arguments()[0]->argumentName() << "; }\n";
  }

  writeFunctionSignature(s, getter, 0, QString(),
                         Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
  s << "{ return theWrappedObject->" << field->name() << "; }\n";
}

void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class)
{
  QString builtIn = ShellGenerator::isBuiltIn(meta_class->name())?"_builtin":"";
  QString pro_file_name = meta_class->package().replace(".", "_") + builtIn + "/" + meta_class->package().replace(".", "_") + builtIn + ".pri";
  priGenerator->addHeader(pro_file_name, fileNameForClass(meta_class));
  setupGenerator->addClass(meta_class->package().replace(".", "_") + builtIn, meta_class);

  QString include_block = "PYTHONQTWRAPPER_" + meta_class->name().toUpper() + "_H";

  s << "#ifndef " << include_block << endl
    << "#define " << include_block << endl << endl;

  Include inc = meta_class->typeEntry()->include();
  ShellGenerator::writeInclude(s, inc);

  s << "#include <QObject>" << endl << endl;
  s << "#include <PythonQt.h>" << endl << endl;

  IncludeList list = meta_class->typeEntry()->extraIncludes();
  qSort(list.begin(), list.end());
  foreach (const Include &inc, list) {
    ShellGenerator::writeInclude(s, inc);
  }
  s << endl;

  AbstractMetaFunctionList ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors
    | AbstractMetaClass::WasVisible
    | AbstractMetaClass::NotRemovedFromTargetLang);

  if (meta_class->qualifiedCppName().contains("Ssl")) {
    s << "#ifndef QT_NO_OPENSSL"  << endl;
  }

  // Shell-------------------------------------------------------------------
  if (meta_class->generateShellClass()) {

    AbstractMetaFunctionList virtualsForShell = getVirtualFunctionsForShell(meta_class);

    s << "class " << shellClassName(meta_class)
      << " : public " << meta_class->qualifiedCppName() << endl << "{" << endl;
    s << "public:" << endl;
    foreach(AbstractMetaFunction* fun, ctors) {
      s << "    ";
      writeFunctionSignature(s, fun, 0,"PythonQtShell_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ":" << meta_class->qualifiedCppName() << "(";
      QString scriptFunctionName = fun->originalName();
      AbstractMetaArgumentList args = fun->arguments();
      for (int i = 0; i < args.size(); ++i) {
        if (i > 0)
          s << ", ";
        s << args.at(i)->argumentName();
      }
      s << "),_wrapper(NULL) {};" << endl;
    }
    s << endl;
    s << "   ~" << shellClassName(meta_class) << "();" << endl;

    foreach(AbstractMetaFunction* fun, virtualsForShell) {
      s << "virtual ";
      writeFunctionSignature(s, fun, 0, QString(),
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ";" << endl;
    }
    s << endl;
    s << "  PythonQtInstanceWrapper* _wrapper; " << endl;

    s << "};" << endl << endl;
  }

  // Promoter-------------------------------------------------------------------
  AbstractMetaFunctionList promoteFunctions = getProtectedFunctionsThatNeedPromotion(meta_class);
  if (!promoteFunctions.isEmpty()) {
    s << "class " << promoterClassName(meta_class)
      << " : public " << meta_class->qualifiedCppName() << endl << "{ public:" << endl;

    foreach(AbstractMetaFunction* fun, promoteFunctions) {
      s << "inline ";
      writeFunctionSignature(s, fun, 0, "promoted_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << " { ";
      QString scriptFunctionName = fun->originalName();
      AbstractMetaArgumentList args = fun->arguments();
      if (fun->type())
        s << "return ";
      s << meta_class->qualifiedCppName() << "::";
      s << fun->originalName() << "(";
      for (int i = 0; i < args.size(); ++i) {
        if (i > 0)
          s << ", ";
        s << args.at(i)->argumentName();
      }
      s << "); }" << endl;
    }

    s << "};" << endl << endl;
  }

  // Wrapper-------------------------------------------------------------------

  s << "class " << wrapperClassName(meta_class)
    << " : public QObject" << endl
    << "{ Q_OBJECT" << endl;

  s << "public:" << endl;

  AbstractMetaEnumList enums1 = meta_class->enums();
  AbstractMetaEnumList enums;
  QList<FlagsTypeEntry*> flags;
  foreach(AbstractMetaEnum* enum1, enums1) {
    // catch gadgets and enums that are not exported on QObjects...
    if (enum1->wasPublic() && (!meta_class->isQObject() || !enum1->hasQEnumsDeclaration())) {
      enums << enum1;
      if (enum1->typeEntry()->flags()) {
        flags << enum1->typeEntry()->flags();
      }
    }
  }
  if (enums.count()) {
    s << "Q_ENUMS(";
    foreach(AbstractMetaEnum* enum1, enums) {
      s << enum1->name() << " ";
    }
    s << ")" << endl;

    if (flags.count()) {
      s << "Q_FLAGS(";
      foreach(FlagsTypeEntry* flag1, flags) {
        QString origName = flag1->originalName();
        int idx = origName.lastIndexOf("::");
        if (idx!= -1) {
          origName = origName.mid(idx+2);
        }
        s << origName << " ";
      }
      s << ")" << endl;
    }

    foreach(AbstractMetaEnum* enum1, enums) {
      s << "enum " << enum1->name() << "{" << endl;
      bool first = true;
      foreach(AbstractMetaEnumValue* value, enum1->values()) {
        if (first) { first = false; }
        else { s << ", "; }
        s << "  " << value->name() << " = " << meta_class->qualifiedCppName() << "::" << value->name();
      }
      s << "};" << endl;
    }
    if (flags.count()) {
      foreach(AbstractMetaEnum* enum1, enums) {
        if (enum1->typeEntry()->flags()) {
          QString origName = enum1->typeEntry()->flags()->originalName();
          int idx = origName.lastIndexOf("::");
          if (idx!= -1) {
            origName = origName.mid(idx+2);
          }
          s << "Q_DECLARE_FLAGS("<< origName << ", " << enum1->name() <<")"<<endl;
        }
      }
    }
  }
  s << "public slots:" << endl;
  if (meta_class->generateShellClass() || !meta_class->isAbstract()) {

    bool copyConstructorSeen = false;
    bool defaultConstructorSeen = false;
    foreach (const AbstractMetaFunction *fun, ctors) {
      if (!fun->isPublic() || fun->isAbstract()) { continue; }
      s << meta_class->qualifiedCppName() << "* ";
      writeFunctionSignature(s, fun, 0, "new_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic));
      s << ";" << endl;
      if (fun->arguments().size()==1 && meta_class->qualifiedCppName() == fun->arguments().at(0)->type()->typeEntry()->qualifiedCppName()) {
        copyConstructorSeen = true;
      }
      if (fun->arguments().size()==0) {
        defaultConstructorSeen = true;
      }
    }

    if (meta_class->typeEntry()->isValue()
        && !copyConstructorSeen && defaultConstructorSeen) {
      QString className = meta_class->generateShellClass()?shellClassName(meta_class):meta_class->qualifiedCppName();
      s << meta_class->qualifiedCppName() << "* new_" << meta_class->name() << "(const " << meta_class->qualifiedCppName() << "& other) {" << endl;
      s << className << "* a = new " << className << "();" << endl;
      s << "*((" << meta_class->qualifiedCppName() << "*)a) = other;" << endl;
      s << "return a; }" << endl;
    }
  }
  if (meta_class->hasPublicDestructor() && !meta_class->isNamespace()) {
    s << "void delete_" << meta_class->name() << "(" << meta_class->qualifiedCppName() << "* obj) { delete obj; } ";
    s << endl;
  }

  AbstractMetaFunctionList functions = getFunctionsToWrap(meta_class);

  foreach (const AbstractMetaFunction *function, functions) {
    if (!function->isSlot() || function->isVirtual()) {
      s << "   ";
      writeFunctionSignature(s, function, 0, QString(),
        Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ";" << endl;
    }
  }
  if (meta_class->hasDefaultToStringFunction() || meta_class->hasToStringCapability()) {
    s << "    QString py_toString(" << meta_class->qualifiedCppName() << "*);" << endl;
  }
  if (meta_class->hasDefaultIsNull()) {
    s << "    bool __nonzero__(" << meta_class->qualifiedCppName() << "* obj) { return !obj->isNull(); }" << endl;
  }

  // Field accessors
  foreach (const AbstractMetaField *field, meta_class->fields()) {
    if (field->isPublic()) {
      writeFieldAccessors(s, field);
    }
  }

  writeInjectedCode(s, meta_class);

  s  << "};" << endl << endl;
  if (meta_class->qualifiedCppName().contains("Ssl")) {
    s << "#endif"  << endl << endl;
  }

  s  << "#endif // " << include_block << endl;

}

void ShellHeaderGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class)
{
  CodeSnipList code_snips = meta_class->typeEntry()->codeSnips();
  foreach (const CodeSnip &cs, code_snips) {
    if (cs.language == TypeSystem::PyWrapperDeclaration) {
      s << cs.code() << endl;
    }
  }
}
<commit_msg>readded linefeed<commit_after>/****************************************************************************
**
** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Script Generator project on Qt Labs.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "shellheadergenerator.h"
#include "fileout.h"

#include <QtCore/QDir>

#include <qdebug.h>

QString ShellHeaderGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const
{
  return QString("PythonQtWrapper_%1.h").arg(meta_class->name());
}

void ShellHeaderGenerator::writeFieldAccessors(QTextStream &s, const AbstractMetaField *field)
{
  const AbstractMetaFunction *setter = field->setter();
  const AbstractMetaFunction *getter = field->getter();

  // static fields are not supported (yet?)
  if (setter->isStatic()) return;

  // Uuid data4 did not work (TODO: move to typesystem...(
  if (field->enclosingClass()->name()=="QUuid" &&  setter->name()=="data4") return;
  if (field->enclosingClass()->name()=="QIPv6Address") return;

  if (!field->type()->isConstant()) {
    writeFunctionSignature(s, setter, 0, QString(),
                           Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | ShowStatic | UnderscoreSpaces));
    s << "{ theWrappedObject->" << field->name() << " = " << setter->arguments()[0]->argumentName() << "; }\n";
  }

  writeFunctionSignature(s, getter, 0, QString(),
                         Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
  s << "{ return theWrappedObject->" << field->name() << "; }\n";
}

void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class)
{
  QString builtIn = ShellGenerator::isBuiltIn(meta_class->name())?"_builtin":"";
  QString pro_file_name = meta_class->package().replace(".", "_") + builtIn + "/" + meta_class->package().replace(".", "_") + builtIn + ".pri";
  priGenerator->addHeader(pro_file_name, fileNameForClass(meta_class));
  setupGenerator->addClass(meta_class->package().replace(".", "_") + builtIn, meta_class);

  QString include_block = "PYTHONQTWRAPPER_" + meta_class->name().toUpper() + "_H";

  s << "#ifndef " << include_block << endl
    << "#define " << include_block << endl << endl;

  Include inc = meta_class->typeEntry()->include();
  ShellGenerator::writeInclude(s, inc);

  s << "#include <QObject>" << endl << endl;
  s << "#include <PythonQt.h>" << endl << endl;

  IncludeList list = meta_class->typeEntry()->extraIncludes();
  qSort(list.begin(), list.end());
  foreach (const Include &inc, list) {
    ShellGenerator::writeInclude(s, inc);
  }
  s << endl;

  AbstractMetaFunctionList ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors
    | AbstractMetaClass::WasVisible
    | AbstractMetaClass::NotRemovedFromTargetLang);

  if (meta_class->qualifiedCppName().contains("Ssl")) {
    s << "#ifndef QT_NO_OPENSSL"  << endl;
  }

  // Shell-------------------------------------------------------------------
  if (meta_class->generateShellClass()) {

    AbstractMetaFunctionList virtualsForShell = getVirtualFunctionsForShell(meta_class);

    s << "class " << shellClassName(meta_class)
      << " : public " << meta_class->qualifiedCppName() << endl << "{" << endl;
    s << "public:" << endl;
    foreach(AbstractMetaFunction* fun, ctors) {
      s << "    ";
      writeFunctionSignature(s, fun, 0,"PythonQtShell_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ":" << meta_class->qualifiedCppName() << "(";
      QString scriptFunctionName = fun->originalName();
      AbstractMetaArgumentList args = fun->arguments();
      for (int i = 0; i < args.size(); ++i) {
        if (i > 0)
          s << ", ";
        s << args.at(i)->argumentName();
      }
      s << "),_wrapper(NULL) {};" << endl;
    }
    s << endl;
    s << "   ~" << shellClassName(meta_class) << "();" << endl;
    s << endl;

    foreach(AbstractMetaFunction* fun, virtualsForShell) {
      s << "virtual ";
      writeFunctionSignature(s, fun, 0, QString(),
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ";" << endl;
    }
    s << endl;
    s << "  PythonQtInstanceWrapper* _wrapper; " << endl;

    s << "};" << endl << endl;
  }

  // Promoter-------------------------------------------------------------------
  AbstractMetaFunctionList promoteFunctions = getProtectedFunctionsThatNeedPromotion(meta_class);
  if (!promoteFunctions.isEmpty()) {
    s << "class " << promoterClassName(meta_class)
      << " : public " << meta_class->qualifiedCppName() << endl << "{ public:" << endl;

    foreach(AbstractMetaFunction* fun, promoteFunctions) {
      s << "inline ";
      writeFunctionSignature(s, fun, 0, "promoted_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << " { ";
      QString scriptFunctionName = fun->originalName();
      AbstractMetaArgumentList args = fun->arguments();
      if (fun->type())
        s << "return ";
      s << meta_class->qualifiedCppName() << "::";
      s << fun->originalName() << "(";
      for (int i = 0; i < args.size(); ++i) {
        if (i > 0)
          s << ", ";
        s << args.at(i)->argumentName();
      }
      s << "); }" << endl;
    }

    s << "};" << endl << endl;
  }

  // Wrapper-------------------------------------------------------------------

  s << "class " << wrapperClassName(meta_class)
    << " : public QObject" << endl
    << "{ Q_OBJECT" << endl;

  s << "public:" << endl;

  AbstractMetaEnumList enums1 = meta_class->enums();
  AbstractMetaEnumList enums;
  QList<FlagsTypeEntry*> flags;
  foreach(AbstractMetaEnum* enum1, enums1) {
    // catch gadgets and enums that are not exported on QObjects...
    if (enum1->wasPublic() && (!meta_class->isQObject() || !enum1->hasQEnumsDeclaration())) {
      enums << enum1;
      if (enum1->typeEntry()->flags()) {
        flags << enum1->typeEntry()->flags();
      }
    }
  }
  if (enums.count()) {
    s << "Q_ENUMS(";
    foreach(AbstractMetaEnum* enum1, enums) {
      s << enum1->name() << " ";
    }
    s << ")" << endl;

    if (flags.count()) {
      s << "Q_FLAGS(";
      foreach(FlagsTypeEntry* flag1, flags) {
        QString origName = flag1->originalName();
        int idx = origName.lastIndexOf("::");
        if (idx!= -1) {
          origName = origName.mid(idx+2);
        }
        s << origName << " ";
      }
      s << ")" << endl;
    }

    foreach(AbstractMetaEnum* enum1, enums) {
      s << "enum " << enum1->name() << "{" << endl;
      bool first = true;
      foreach(AbstractMetaEnumValue* value, enum1->values()) {
        if (first) { first = false; }
        else { s << ", "; }
        s << "  " << value->name() << " = " << meta_class->qualifiedCppName() << "::" << value->name();
      }
      s << "};" << endl;
    }
    if (flags.count()) {
      foreach(AbstractMetaEnum* enum1, enums) {
        if (enum1->typeEntry()->flags()) {
          QString origName = enum1->typeEntry()->flags()->originalName();
          int idx = origName.lastIndexOf("::");
          if (idx!= -1) {
            origName = origName.mid(idx+2);
          }
          s << "Q_DECLARE_FLAGS("<< origName << ", " << enum1->name() <<")"<<endl;
        }
      }
    }
  }
  s << "public slots:" << endl;
  if (meta_class->generateShellClass() || !meta_class->isAbstract()) {

    bool copyConstructorSeen = false;
    bool defaultConstructorSeen = false;
    foreach (const AbstractMetaFunction *fun, ctors) {
      if (!fun->isPublic() || fun->isAbstract()) { continue; }
      s << meta_class->qualifiedCppName() << "* ";
      writeFunctionSignature(s, fun, 0, "new_",
        Option(IncludeDefaultExpression | OriginalName | ShowStatic));
      s << ";" << endl;
      if (fun->arguments().size()==1 && meta_class->qualifiedCppName() == fun->arguments().at(0)->type()->typeEntry()->qualifiedCppName()) {
        copyConstructorSeen = true;
      }
      if (fun->arguments().size()==0) {
        defaultConstructorSeen = true;
      }
    }

    if (meta_class->typeEntry()->isValue()
        && !copyConstructorSeen && defaultConstructorSeen) {
      QString className = meta_class->generateShellClass()?shellClassName(meta_class):meta_class->qualifiedCppName();
      s << meta_class->qualifiedCppName() << "* new_" << meta_class->name() << "(const " << meta_class->qualifiedCppName() << "& other) {" << endl;
      s << className << "* a = new " << className << "();" << endl;
      s << "*((" << meta_class->qualifiedCppName() << "*)a) = other;" << endl;
      s << "return a; }" << endl;
    }
  }
  if (meta_class->hasPublicDestructor() && !meta_class->isNamespace()) {
    s << "void delete_" << meta_class->name() << "(" << meta_class->qualifiedCppName() << "* obj) { delete obj; } ";
    s << endl;
  }

  AbstractMetaFunctionList functions = getFunctionsToWrap(meta_class);

  foreach (const AbstractMetaFunction *function, functions) {
    if (!function->isSlot() || function->isVirtual()) {
      s << "   ";
      writeFunctionSignature(s, function, 0, QString(),
        Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
      s << ";" << endl;
    }
  }
  if (meta_class->hasDefaultToStringFunction() || meta_class->hasToStringCapability()) {
    s << "    QString py_toString(" << meta_class->qualifiedCppName() << "*);" << endl;
  }
  if (meta_class->hasDefaultIsNull()) {
    s << "    bool __nonzero__(" << meta_class->qualifiedCppName() << "* obj) { return !obj->isNull(); }" << endl;
  }

  // Field accessors
  foreach (const AbstractMetaField *field, meta_class->fields()) {
    if (field->isPublic()) {
      writeFieldAccessors(s, field);
    }
  }

  writeInjectedCode(s, meta_class);

  s  << "};" << endl << endl;
  if (meta_class->qualifiedCppName().contains("Ssl")) {
    s << "#endif"  << endl << endl;
  }

  s  << "#endif // " << include_block << endl;

}

void ShellHeaderGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class)
{
  CodeSnipList code_snips = meta_class->typeEntry()->codeSnips();
  foreach (const CodeSnip &cs, code_snips) {
    if (cs.language == TypeSystem::PyWrapperDeclaration) {
      s << cs.code() << endl;
    }
  }
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkHeap.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 "vtkHeap.h"
#include "vtkObjectFactory.h"

vtkCxxRevisionMacro(vtkHeap, "1.15");
vtkStandardNewMacro(vtkHeap);

struct vtkTestAlignLong
{
  char    pad;
  long    x;
};

static int vtkGetLongAlignment()
{
  struct vtkTestAlignLong    s1;
  char *               p1;
  char *               p2;

  p1 = reinterpret_cast<char *>(&s1);   // Get address of struct
  p2 = reinterpret_cast<char *>(&s1.x); // Get address of long within struct

  return (p2 - p1);    // Get member offset/alignment
}

class VTK_COMMON_EXPORT vtkHeapBlock
{
public:
  char*         Data;
  vtkHeapBlock* Next;
  size_t        Size; //Variable size guards against block size changing from SetBlockSize()
                      //or large requests greater than the standard block size.

  vtkHeapBlock(size_t size):Next(0),Size(size)
    {this->Data = new char [size];}
  ~vtkHeapBlock()
    {delete [] this->Data;}
};

vtkHeap::vtkHeap()
{
  this->BlockSize = 256000;
  this->NumberOfBlocks = 0;
  this->NumberOfAllocations = 0;
  this->Alignment = vtkGetLongAlignment();
  this->First = 0;
  this->Last = 0;
  this->Current = 0;
  this->Position = 0;
}

vtkHeap::~vtkHeap()
{
  this->CleanAll();
}

void vtkHeap::SetBlockSize(size_t _arg)
{
  vtkDebugMacro(
    << this->GetClassName() << " (" << this << "): setting BlockSize to "
    << static_cast<int>(_arg));
  if (this->BlockSize != _arg)
    {
    this->BlockSize = _arg;
    this->Modified();
    }
}

void* vtkHeap::AllocateMemory(size_t n)
{
  if ( n%this->Alignment ) //4-byte word alignement
    {
    n += this->Alignment - (n%this->Alignment);
    }

  size_t blockSize = (n > this->BlockSize ? n : this->BlockSize );
  this->NumberOfAllocations++;

  if ( ! this->Current ||
       (this->Position + n) >= this->Current->Size )
    {
    this->Add(blockSize);
    }

  char *ptr = this->Current->Data + this->Position;
  this->Position += n;

  return ptr;
}

// If a Reset() was invoked, then we reuse memory (i.e., the list of blocks)
// or allocate it as necessary. Otherwise a block is allocated and placed into
// the list of blocks.
void vtkHeap::Add(size_t blockSize)
{
  this->Position = 0; //reset to the beginning of the block

  if ( this->Current && this->Current != this->Last &&
       this->Current->Next->Size >= blockSize ) //reuse
    {
    this->Current = this->Current->Next;
    }

  else //allocate a new block
    {
    this->NumberOfBlocks++;
    vtkHeapBlock* block = new vtkHeapBlock(blockSize);

    if (!this->Last)
      {
      this->First = block;
      this->Current = block;
      this->Last = block;
      return;
      }

    this->Last->Next = block;
    this->Last = block;
    this->Current = block;
    }
}

void vtkHeap::CleanAll()
{
  this->Current = this->First;
  if (!this->Current) { return; }
  while (this->DeleteAndNext());
  this->First = this->Current = this->Last = 0;
  this->Position = 0;
}

vtkHeapBlock* vtkHeap::DeleteAndNext()
{
  if (this->Current)
    {
    vtkHeapBlock* tmp = this->Current;
    this->Current = this->Current->Next;
    delete tmp;
    return this->Current;
    }
  else
    {
    return 0;
    }
}

void vtkHeap::Reset()
{
  this->Current = this->First;
  this->Position = 0;
}

char* vtkHeap::StringDup(const char* str)
{
  char *newStr = static_cast<char*>(this->AllocateMemory(strlen(str)+1));
  strcpy(newStr,str);
  return newStr;
}

void vtkHeap::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Block Size: " << static_cast<int>(this->BlockSize) << "\n";
  os << indent << "Number of Blocks: " << this->NumberOfBlocks << "\n";
  os << indent << "Number of Allocations: " << this->NumberOfAllocations << "\n";
  os << indent << "Current bytes allocated: "
     << ((this->NumberOfBlocks-1)*static_cast<int>(this->BlockSize) +
         static_cast<int>(this->Position)) << "\n";
}

<commit_msg>ENH: Merge changes from main tree into VTK-5-2 branch. (cvs -q up -j1.15 -j1.16 Common/vtkHeap.cxx)<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkHeap.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 "vtkHeap.h"
#include "vtkObjectFactory.h"

vtkCxxRevisionMacro(vtkHeap, "1.15.4.1");
vtkStandardNewMacro(vtkHeap);

struct vtkTestAlignLong
{
  char    pad;
  long    x;
};

static int vtkGetLongAlignment()
{
  struct vtkTestAlignLong    s1;
  char *               p1;
  char *               p2;

  p1 = reinterpret_cast<char *>(&s1);   // Get address of struct
  p2 = reinterpret_cast<char *>(&s1.x); // Get address of long within struct

  return (p2 - p1);    // Get member offset/alignment
}

class VTK_COMMON_EXPORT vtkHeapBlock
{
public:
  char*         Data;
  vtkHeapBlock* Next;
  size_t        Size; //Variable size guards against block size changing from SetBlockSize()
                      //or large requests greater than the standard block size.

  vtkHeapBlock(size_t size):Next(0),Size(size)
    {this->Data = new char [size];}
  ~vtkHeapBlock()
    {delete [] this->Data;}
};

vtkHeap::vtkHeap()
{
  this->BlockSize = 256000;
  this->NumberOfBlocks = 0;
  this->NumberOfAllocations = 0;
  this->Alignment = vtkGetLongAlignment();
  this->First = 0;
  this->Last = 0;
  this->Current = 0;
  this->Position = 0;
}

vtkHeap::~vtkHeap()
{
  this->CleanAll();
}

void vtkHeap::SetBlockSize(size_t _arg)
{
  vtkDebugMacro(
    << this->GetClassName() << " (" << this << "): setting BlockSize to "
    << static_cast<int>(_arg));
  if (this->BlockSize != _arg)
    {
    this->BlockSize = _arg;
    this->Modified();
    }
}

void* vtkHeap::AllocateMemory(size_t n)
{
  if ( n%this->Alignment ) //4-byte word alignement
    {
    n += this->Alignment - (n%this->Alignment);
    }

  size_t blockSize = (n > this->BlockSize ? n : this->BlockSize );
  this->NumberOfAllocations++;

  if ( ! this->Current ||
       (this->Position + n) >= this->Current->Size )
    {
    this->Add(blockSize);
    }

  char *ptr = this->Current->Data + this->Position;
  this->Position += n;

  return ptr;
}

// If a Reset() was invoked, then we reuse memory (i.e., the list of blocks)
// or allocate it as necessary. Otherwise a block is allocated and placed into
// the list of blocks.
void vtkHeap::Add(size_t blockSize)
{
  this->Position = 0; //reset to the beginning of the block

  if ( this->Current && this->Current != this->Last &&
       this->Current->Next->Size >= blockSize ) //reuse
    {
    this->Current = this->Current->Next;
    }

  else //allocate a new block
    {
    this->NumberOfBlocks++;
    vtkHeapBlock* block = new vtkHeapBlock(blockSize);

    if (!this->Last)
      {
      this->First = block;
      this->Current = block;
      this->Last = block;
      return;
      }

    this->Last->Next = block;
    this->Last = block;
    this->Current = block;
    }
}

void vtkHeap::CleanAll()
{
  this->Current = this->First;
  if (!this->Current) { return; }
  while (this->DeleteAndNext())
    {
    ;
    }
  this->First = this->Current = this->Last = 0;
  this->Position = 0;
}

vtkHeapBlock* vtkHeap::DeleteAndNext()
{
  if (this->Current)
    {
    vtkHeapBlock* tmp = this->Current;
    this->Current = this->Current->Next;
    delete tmp;
    return this->Current;
    }
  else
    {
    return 0;
    }
}

void vtkHeap::Reset()
{
  this->Current = this->First;
  this->Position = 0;
}

char* vtkHeap::StringDup(const char* str)
{
  char *newStr = static_cast<char*>(this->AllocateMemory(strlen(str)+1));
  strcpy(newStr,str);
  return newStr;
}

void vtkHeap::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Block Size: " << static_cast<int>(this->BlockSize) << "\n";
  os << indent << "Number of Blocks: " << this->NumberOfBlocks << "\n";
  os << indent << "Number of Allocations: " << this->NumberOfAllocations << "\n";
  os << indent << "Current bytes allocated: "
     << ((this->NumberOfBlocks-1)*static_cast<int>(this->BlockSize) +
         static_cast<int>(this->Position)) << "\n";
}

<|endoftext|>


<commit_before>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/api/atom_api_tray.h"

#include <string>

#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/browser.h"
#include "atom/common/api/atom_api_native_image.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/node_includes.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "ui/gfx/image/image.h"

namespace mate {

template<>
struct Converter<atom::TrayIcon::HighlightMode> {
  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
                     atom::TrayIcon::HighlightMode* out) {
    std::string mode;
    if (ConvertFromV8(isolate, val, &mode)) {
      if (mode == "always") {
        *out = atom::TrayIcon::HighlightMode::ALWAYS;
        return true;
      }
      if (mode == "selection") {
        *out = atom::TrayIcon::HighlightMode::SELECTION;
        return true;
      }
      if (mode == "never") {
        *out = atom::TrayIcon::HighlightMode::NEVER;
        return true;
      }
    }

    // Support old boolean parameter
    bool highlight;
    if (ConvertFromV8(isolate, val, &highlight)) {
      if (highlight)
        *out = atom::TrayIcon::HighlightMode::SELECTION;
      else
        *out = atom::TrayIcon::HighlightMode::NEVER;
      return true;
    }

    return false;
  }
};
}  // namespace mate

namespace atom {

namespace api {

Tray::Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image)
    : tray_icon_(TrayIcon::Create()) {
  SetImage(isolate, image);
  tray_icon_->AddObserver(this);
}

Tray::~Tray() {
  // Destroy the native tray in next tick.
  base::MessageLoop::current()->DeleteSoon(FROM_HERE, tray_icon_.release());
}

// static
mate::WrappableBase* Tray::New(v8::Isolate* isolate,
                               mate::Handle<NativeImage> image) {
  if (!Browser::Get()->is_ready()) {
    isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
        isolate, "Cannot create Tray before app is ready")));
    return nullptr;
  }
  return new Tray(isolate, image);
}

void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
  EmitWithFlags("click", modifiers, bounds);
}

void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
  EmitWithFlags("double-click", modifiers, bounds);
}

void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) {
  EmitWithFlags("right-click", modifiers, bounds);
}

void Tray::OnBalloonShow() {
  Emit("balloon-show");
}

void Tray::OnBalloonClicked() {
  Emit("balloon-click");
}

void Tray::OnBalloonClosed() {
  Emit("balloon-closed");
}

void Tray::OnDrop() {
  Emit("drop");
}

void Tray::OnDropFiles(const std::vector<std::string>& files) {
  Emit("drop-files", files);
}

void Tray::OnDropText(const std::string& text) {
  Emit("drop-text", text);
}

void Tray::OnDragEntered() {
  Emit("drag-enter");
}

void Tray::OnDragExited() {
  Emit("drag-leave");
}

void Tray::OnDragEnded() {
  Emit("drag-end");
}

void Tray::SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image) {
#if defined(OS_WIN)
  tray_icon_->SetImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
#else
  tray_icon_->SetImage(image->image());
#endif
}

void Tray::SetPressedImage(v8::Isolate* isolate,
                           mate::Handle<NativeImage> image) {
#if defined(OS_WIN)
  tray_icon_->SetPressedImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
#else
  tray_icon_->SetPressedImage(image->image());
#endif
}

void Tray::SetToolTip(const std::string& tool_tip) {
  tray_icon_->SetToolTip(tool_tip);
}

void Tray::SetTitle(const std::string& title) {
  tray_icon_->SetTitle(title);
}

void Tray::SetHighlightMode(TrayIcon::HighlightMode mode) {
  tray_icon_->SetHighlightMode(mode);
}

void Tray::DisplayBalloon(mate::Arguments* args,
                          const mate::Dictionary& options) {
  mate::Handle<NativeImage> icon;
  options.Get("icon", &icon);
  base::string16 title, content;
  if (!options.Get("title", &title) ||
      !options.Get("content", &content)) {
    args->ThrowError("'title' and 'content' must be defined");
    return;
  }

#if defined(OS_WIN)
  tray_icon_->DisplayBalloon(
      icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
      title, content);
#else
  tray_icon_->DisplayBalloon(
      icon.IsEmpty() ? gfx::Image() : icon->image(), title, content);
#endif
}

void Tray::PopUpContextMenu(mate::Arguments* args) {
  mate::Handle<Menu> menu;
  args->GetNext(&menu);
  gfx::Point pos;
  args->GetNext(&pos);
  tray_icon_->PopUpContextMenu(pos, menu.IsEmpty() ? nullptr : menu->model());
}

void Tray::SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu) {
  menu_.Reset(isolate, menu.ToV8());
  tray_icon_->SetContextMenu(menu->model());
}

gfx::Rect Tray::GetBounds() {
  return tray_icon_->GetBounds();
}

// static
void Tray::BuildPrototype(v8::Isolate* isolate,
                          v8::Local<v8::ObjectTemplate> prototype) {
  mate::ObjectTemplateBuilder(isolate, prototype)
      .MakeDestroyable()
      .SetMethod("setImage", &Tray::SetImage)
      .SetMethod("setPressedImage", &Tray::SetPressedImage)
      .SetMethod("setToolTip", &Tray::SetToolTip)
      .SetMethod("setTitle", &Tray::SetTitle)
      .SetMethod("setHighlightMode", &Tray::SetHighlightMode)
      .SetMethod("displayBalloon", &Tray::DisplayBalloon)
      .SetMethod("popUpContextMenu", &Tray::PopUpContextMenu)
      .SetMethod("setContextMenu", &Tray::SetContextMenu)
      .SetMethod("getBounds", &Tray::GetBounds);
}

}  // namespace api

}  // namespace atom

namespace {

void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
                v8::Local<v8::Context> context, void* priv) {
  using atom::api::Tray;
  v8::Isolate* isolate = context->GetIsolate();
  v8::Local<v8::Function> constructor = mate::CreateConstructor<Tray>(
      isolate, "Tray", base::Bind(&Tray::New));
  mate::Dictionary dict(isolate, exports);
  dict.Set("Tray", static_cast<v8::Local<v8::Value>>(constructor));
}

}  // namespace

NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_tray, Initialize)
<commit_msg>Add TODO to deprecate boolean param<commit_after>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/api/atom_api_tray.h"

#include <string>

#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/browser.h"
#include "atom/common/api/atom_api_native_image.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/node_includes.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "ui/gfx/image/image.h"

namespace mate {

template<>
struct Converter<atom::TrayIcon::HighlightMode> {
  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
                     atom::TrayIcon::HighlightMode* out) {
    std::string mode;
    if (ConvertFromV8(isolate, val, &mode)) {
      if (mode == "always") {
        *out = atom::TrayIcon::HighlightMode::ALWAYS;
        return true;
      }
      if (mode == "selection") {
        *out = atom::TrayIcon::HighlightMode::SELECTION;
        return true;
      }
      if (mode == "never") {
        *out = atom::TrayIcon::HighlightMode::NEVER;
        return true;
      }
    }

    // Support old boolean parameter
    // TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
    bool highlight;
    if (ConvertFromV8(isolate, val, &highlight)) {
      if (highlight)
        *out = atom::TrayIcon::HighlightMode::SELECTION;
      else
        *out = atom::TrayIcon::HighlightMode::NEVER;
      return true;
    }

    return false;
  }
};
}  // namespace mate

namespace atom {

namespace api {

Tray::Tray(v8::Isolate* isolate, mate::Handle<NativeImage> image)
    : tray_icon_(TrayIcon::Create()) {
  SetImage(isolate, image);
  tray_icon_->AddObserver(this);
}

Tray::~Tray() {
  // Destroy the native tray in next tick.
  base::MessageLoop::current()->DeleteSoon(FROM_HERE, tray_icon_.release());
}

// static
mate::WrappableBase* Tray::New(v8::Isolate* isolate,
                               mate::Handle<NativeImage> image) {
  if (!Browser::Get()->is_ready()) {
    isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
        isolate, "Cannot create Tray before app is ready")));
    return nullptr;
  }
  return new Tray(isolate, image);
}

void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
  EmitWithFlags("click", modifiers, bounds);
}

void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
  EmitWithFlags("double-click", modifiers, bounds);
}

void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) {
  EmitWithFlags("right-click", modifiers, bounds);
}

void Tray::OnBalloonShow() {
  Emit("balloon-show");
}

void Tray::OnBalloonClicked() {
  Emit("balloon-click");
}

void Tray::OnBalloonClosed() {
  Emit("balloon-closed");
}

void Tray::OnDrop() {
  Emit("drop");
}

void Tray::OnDropFiles(const std::vector<std::string>& files) {
  Emit("drop-files", files);
}

void Tray::OnDropText(const std::string& text) {
  Emit("drop-text", text);
}

void Tray::OnDragEntered() {
  Emit("drag-enter");
}

void Tray::OnDragExited() {
  Emit("drag-leave");
}

void Tray::OnDragEnded() {
  Emit("drag-end");
}

void Tray::SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image) {
#if defined(OS_WIN)
  tray_icon_->SetImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
#else
  tray_icon_->SetImage(image->image());
#endif
}

void Tray::SetPressedImage(v8::Isolate* isolate,
                           mate::Handle<NativeImage> image) {
#if defined(OS_WIN)
  tray_icon_->SetPressedImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
#else
  tray_icon_->SetPressedImage(image->image());
#endif
}

void Tray::SetToolTip(const std::string& tool_tip) {
  tray_icon_->SetToolTip(tool_tip);
}

void Tray::SetTitle(const std::string& title) {
  tray_icon_->SetTitle(title);
}

void Tray::SetHighlightMode(TrayIcon::HighlightMode mode) {
  tray_icon_->SetHighlightMode(mode);
}

void Tray::DisplayBalloon(mate::Arguments* args,
                          const mate::Dictionary& options) {
  mate::Handle<NativeImage> icon;
  options.Get("icon", &icon);
  base::string16 title, content;
  if (!options.Get("title", &title) ||
      !options.Get("content", &content)) {
    args->ThrowError("'title' and 'content' must be defined");
    return;
  }

#if defined(OS_WIN)
  tray_icon_->DisplayBalloon(
      icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
      title, content);
#else
  tray_icon_->DisplayBalloon(
      icon.IsEmpty() ? gfx::Image() : icon->image(), title, content);
#endif
}

void Tray::PopUpContextMenu(mate::Arguments* args) {
  mate::Handle<Menu> menu;
  args->GetNext(&menu);
  gfx::Point pos;
  args->GetNext(&pos);
  tray_icon_->PopUpContextMenu(pos, menu.IsEmpty() ? nullptr : menu->model());
}

void Tray::SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu) {
  menu_.Reset(isolate, menu.ToV8());
  tray_icon_->SetContextMenu(menu->model());
}

gfx::Rect Tray::GetBounds() {
  return tray_icon_->GetBounds();
}

// static
void Tray::BuildPrototype(v8::Isolate* isolate,
                          v8::Local<v8::ObjectTemplate> prototype) {
  mate::ObjectTemplateBuilder(isolate, prototype)
      .MakeDestroyable()
      .SetMethod("setImage", &Tray::SetImage)
      .SetMethod("setPressedImage", &Tray::SetPressedImage)
      .SetMethod("setToolTip", &Tray::SetToolTip)
      .SetMethod("setTitle", &Tray::SetTitle)
      .SetMethod("setHighlightMode", &Tray::SetHighlightMode)
      .SetMethod("displayBalloon", &Tray::DisplayBalloon)
      .SetMethod("popUpContextMenu", &Tray::PopUpContextMenu)
      .SetMethod("setContextMenu", &Tray::SetContextMenu)
      .SetMethod("getBounds", &Tray::GetBounds);
}

}  // namespace api

}  // namespace atom

namespace {

void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
                v8::Local<v8::Context> context, void* priv) {
  using atom::api::Tray;
  v8::Isolate* isolate = context->GetIsolate();
  v8::Local<v8::Function> constructor = mate::CreateConstructor<Tray>(
      isolate, "Tray", base::Bind(&Tray::New));
  mate::Dictionary dict(isolate, exports);
  dict.Set("Tray", static_cast<v8::Local<v8::Value>>(constructor));
}

}  // namespace

NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_tray, Initialize)
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_LA_SOLVER_ISTL_AMG_HH
#define DUNE_STUFF_LA_SOLVER_ISTL_AMG_HH

#include <type_traits>
#include <cmath>

#if HAVE_DUNE_ISTL
# include <dune/istl/operators.hh>
# include <dune/istl/solvers.hh>
# include <dune/stuff/common/disable_warnings.hh>
#   include <dune/istl/paamg/amg.hh>
#   include <dune/istl/preconditioners.hh>
# include <dune/stuff/common/reenable_warnings.hh>
#endif // HAVE_DUNE_ISTL

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/parameter/configcontainer.hh>
#include <dune/stuff/common/parallel/helper.hh>
#include <dune/stuff/la/container/istl.hh>

namespace Dune {
namespace Stuff {
namespace LA {

#if HAVE_DUNE_ISTL

//! the general, parallel case
template< class S, class CommunicatorType >
class AmgApplicator
{
  typedef IstlRowMajorSparseMatrix< S >  MatrixType;
  typedef typename MatrixType::BackendType           IstlMatrixType;
  typedef typename IstlDenseVector< S >::BackendType IstlVectorType;

public:
  AmgApplicator(const MatrixType& matrix,
                const CommunicatorType& comm)
    : matrix_(matrix)
    , communicator_(comm)
  {}

  InverseOperatorResult call(IstlDenseVector< S >& rhs,
                             IstlDenseVector< S >& solution,
                             const Common::ConfigContainer& opts,
                             const Common::ConfigContainer& default_opts)
  {
    // define the matrix operator

    typedef OverlappingSchwarzOperator< IstlMatrixType, IstlVectorType, IstlVectorType, CommunicatorType >
        MatrixOperatorType;
    MatrixOperatorType matrix_operator(matrix_.backend(), communicator_);

    // define the scalar product
    OverlappingSchwarzScalarProduct< IstlVectorType, CommunicatorType > scalar_product(communicator_);

    // define ILU0 as the smoother for the AMG
    typedef SeqILU0< IstlMatrixType, IstlVectorType, IstlVectorType, 1 > SequentialSmootherType;
    typedef BlockPreconditioner< IstlVectorType, IstlVectorType,
        CommunicatorType,
        SequentialSmootherType> SmootherType;
    typename Amg::SmootherTraits< SmootherType >::Arguments smoother_parameters;
    smoother_parameters.iterations = opts.get("smoother.iterations",
                                              default_opts.get< size_t >("smoother.iterations"));
    smoother_parameters.relaxationFactor = opts.get("smoother.relaxation_factor",
                                                    default_opts.get< S >("smoother.relaxation_factor"));

    // define the AMG as the preconditioner for the BiCGStab solver
    Amg::Parameters amg_parameters(opts.get("preconditioner.max_level",
                                            default_opts.get< size_t >("preconditioner.max_level")),
                                   opts.get("preconditioner.coarse_target",
                                            default_opts.get< size_t >("preconditioner.coarse_target")),
                                   opts.get("preconditioner.min_coarse_rate",
                                            default_opts.get< S >("preconditioner.min_coarse_rate")),
                                   opts.get("preconditioner.prolong_damp",
                                            default_opts.get< S >("preconditioner.prolong_damp")));
    amg_parameters.setDefaultValuesIsotropic(opts.get("preconditioner.isotropy_dim",
                                                      default_opts.get< size_t >("preconditioner.isotropy_dim")));
    amg_parameters.setDefaultValuesAnisotropic(opts.get("preconditioner.anisotropy_dim",
                                                        default_opts.get< size_t >("preconditioner.anisotropy_dim")));
    amg_parameters.setDebugLevel(opts.get("preconditioner.verbose",
                                          default_opts.get< int >("preconditioner.verbose")));
    Amg::CoarsenCriterion< Amg::SymmetricCriterion< IstlMatrixType, Amg::FirstDiagonal > >
        amg_criterion(amg_parameters);
    typedef Amg::AMG< MatrixOperatorType, IstlVectorType, SmootherType, CommunicatorType > PreconditionerType;
    PreconditionerType preconditioner(matrix_operator, amg_criterion, smoother_parameters, communicator_);

    // define the BiCGStab as the actual solver
    BiCGSTABSolver< IstlVectorType > solver(matrix_operator,
                                            scalar_product,
                                            preconditioner,
                                            opts.get("precision", default_opts.get< S >("precision")),
                                            opts.get("max_iter", default_opts.get< size_t >("max_iter")),
#if HAVE_MPI
                                            (communicator_.communicator().rank() == 0)
                                            ? opts.get("verbose", default_opts.get< int >("verbose"))
                                            : 0
#else // HAVE_MPI
                                            opts.get("verbose", default_opts.get< int >("verbose"))
#endif
                                            );

    InverseOperatorResult stats;
    solver.apply(solution.backend(), rhs.backend(), stats);
    return stats;
  } // ... call(...)
protected:
  const MatrixType& matrix_;
  const CommunicatorType& communicator_;
};

//! specialization for our faux type \ref SequentialCommunication
template< class S >
class AmgApplicator< S, SequentialCommunication >
{
  typedef IstlRowMajorSparseMatrix< S >  MatrixType;
  typedef typename MatrixType::BackendType           IstlMatrixType;
  typedef typename IstlDenseVector< S >::BackendType IstlVectorType;

public:
  AmgApplicator(const MatrixType& matrix, const SequentialCommunication& comm)
    : matrix_(matrix)
    , communicator_(comm)
  {}

  InverseOperatorResult call(IstlDenseVector< S >& rhs,
                             IstlDenseVector< S >& solution,
                             const Common::ConfigContainer& opts,
                             const Common::ConfigContainer& default_opts)
  {
    typedef MatrixAdapter< IstlMatrixType, IstlVectorType, IstlVectorType > MatrixOperatorType;
    MatrixOperatorType matrix_operator(matrix_.backend());

    // define the scalar product
    Dune::SeqScalarProduct< typename IstlDenseVector< S >::BackendType > scalar_product;

    // define ILU0 as the smoother for the AMG

    typedef SeqILU0< IstlMatrixType, IstlVectorType, IstlVectorType > SmootherType;

    typename Amg::SmootherTraits< SmootherType >::Arguments smoother_parameters;
    smoother_parameters.iterations = opts.get("smoother.iterations",
                                              default_opts.get< int >("smoother.iterations"));
    smoother_parameters.relaxationFactor = opts.get("smoother.relaxation_factor",
                                                    default_opts.get< S >("smoother.relaxation_factor"));

    // define the AMG as the preconditioner for the BiCGStab solver
    Amg::Parameters amg_parameters(opts.get("preconditioner.max_level",
                                            default_opts.get< int >("preconditioner.max_level")),
                                   opts.get("preconditioner.coarse_target",
                                            default_opts.get< int >("preconditioner.coarse_target")),
                                   opts.get("preconditioner.min_coarse_rate",
                                            default_opts.get< S >("preconditioner.min_coarse_rate")),
                                   opts.get("preconditioner.prolong_damp",
                                            default_opts.get< S >("preconditioner.prolong_damp")));
    amg_parameters.setDefaultValuesIsotropic(opts.get("preconditioner.isotropy_dim",
                                                      default_opts.get< size_t >("preconditioner.isotropy_dim")));
    amg_parameters.setDefaultValuesAnisotropic(opts.get("preconditioner.anisotropy_dim",
                                                        default_opts.get< size_t >("preconditioner.anisotropy_dim")));
    amg_parameters.setDebugLevel(opts.get("preconditioner.verbose",
                                          default_opts.get< int >("preconditioner.verbose")));
    Amg::CoarsenCriterion< Amg::SymmetricCriterion< IstlMatrixType, Amg::FirstDiagonal > >
        amg_criterion(amg_parameters);

    typedef Amg::AMG< MatrixOperatorType, IstlVectorType, SmootherType > PreconditionerType;
    PreconditionerType preconditioner(matrix_operator, amg_criterion, smoother_parameters);

    // define the BiCGStab as the actual solver
    BiCGSTABSolver< IstlVectorType > solver(matrix_operator,
                                            scalar_product,
                                            preconditioner,
                                            opts.get("precision", default_opts.get< S >("precision")),
                                            opts.get("max_iter", default_opts.get< int >("max_iter")),
                                            opts.get("verbose", default_opts.get< int >("verbose")));
    InverseOperatorResult stats;
    solver.apply(solution.backend(), rhs.backend(), stats);
    return stats;
  } // ... call(...)

protected:
  const MatrixType& matrix_;
  const SequentialCommunication& communicator_;
};

#else //HAVE_DUNE_ISTL

template< class S, class T >
class AmgApplicator
{
  static_assert(Dune::AlwaysFalse< S, T >::value, "You are missing dune-istl!");
};

#endif //HAVE_DUNE_ISTL

} // namespace LA
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_LA_SOLVER_ISTL_AMG_HH
<commit_msg>[la.solver.istl] fixed Dune::AlwaysFalse usage<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_LA_SOLVER_ISTL_AMG_HH
#define DUNE_STUFF_LA_SOLVER_ISTL_AMG_HH

#include <type_traits>
#include <cmath>

#if HAVE_DUNE_ISTL
# include <dune/istl/operators.hh>
# include <dune/istl/solvers.hh>
# include <dune/stuff/common/disable_warnings.hh>
#   include <dune/istl/paamg/amg.hh>
#   include <dune/istl/preconditioners.hh>
# include <dune/stuff/common/reenable_warnings.hh>
#endif // HAVE_DUNE_ISTL

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/parameter/configcontainer.hh>
#include <dune/stuff/common/parallel/helper.hh>
#include <dune/stuff/la/container/istl.hh>

namespace Dune {
namespace Stuff {
namespace LA {

#if HAVE_DUNE_ISTL

//! the general, parallel case
template< class S, class CommunicatorType >
class AmgApplicator
{
  typedef IstlRowMajorSparseMatrix< S >  MatrixType;
  typedef typename MatrixType::BackendType           IstlMatrixType;
  typedef typename IstlDenseVector< S >::BackendType IstlVectorType;

public:
  AmgApplicator(const MatrixType& matrix,
                const CommunicatorType& comm)
    : matrix_(matrix)
    , communicator_(comm)
  {}

  InverseOperatorResult call(IstlDenseVector< S >& rhs,
                             IstlDenseVector< S >& solution,
                             const Common::ConfigContainer& opts,
                             const Common::ConfigContainer& default_opts)
  {
    // define the matrix operator

    typedef OverlappingSchwarzOperator< IstlMatrixType, IstlVectorType, IstlVectorType, CommunicatorType >
        MatrixOperatorType;
    MatrixOperatorType matrix_operator(matrix_.backend(), communicator_);

    // define the scalar product
    OverlappingSchwarzScalarProduct< IstlVectorType, CommunicatorType > scalar_product(communicator_);

    // define ILU0 as the smoother for the AMG
    typedef SeqILU0< IstlMatrixType, IstlVectorType, IstlVectorType, 1 > SequentialSmootherType;
    typedef BlockPreconditioner< IstlVectorType, IstlVectorType,
        CommunicatorType,
        SequentialSmootherType> SmootherType;
    typename Amg::SmootherTraits< SmootherType >::Arguments smoother_parameters;
    smoother_parameters.iterations = opts.get("smoother.iterations",
                                              default_opts.get< size_t >("smoother.iterations"));
    smoother_parameters.relaxationFactor = opts.get("smoother.relaxation_factor",
                                                    default_opts.get< S >("smoother.relaxation_factor"));

    // define the AMG as the preconditioner for the BiCGStab solver
    Amg::Parameters amg_parameters(opts.get("preconditioner.max_level",
                                            default_opts.get< size_t >("preconditioner.max_level")),
                                   opts.get("preconditioner.coarse_target",
                                            default_opts.get< size_t >("preconditioner.coarse_target")),
                                   opts.get("preconditioner.min_coarse_rate",
                                            default_opts.get< S >("preconditioner.min_coarse_rate")),
                                   opts.get("preconditioner.prolong_damp",
                                            default_opts.get< S >("preconditioner.prolong_damp")));
    amg_parameters.setDefaultValuesIsotropic(opts.get("preconditioner.isotropy_dim",
                                                      default_opts.get< size_t >("preconditioner.isotropy_dim")));
    amg_parameters.setDefaultValuesAnisotropic(opts.get("preconditioner.anisotropy_dim",
                                                        default_opts.get< size_t >("preconditioner.anisotropy_dim")));
    amg_parameters.setDebugLevel(opts.get("preconditioner.verbose",
                                          default_opts.get< int >("preconditioner.verbose")));
    Amg::CoarsenCriterion< Amg::SymmetricCriterion< IstlMatrixType, Amg::FirstDiagonal > >
        amg_criterion(amg_parameters);
    typedef Amg::AMG< MatrixOperatorType, IstlVectorType, SmootherType, CommunicatorType > PreconditionerType;
    PreconditionerType preconditioner(matrix_operator, amg_criterion, smoother_parameters, communicator_);

    // define the BiCGStab as the actual solver
    BiCGSTABSolver< IstlVectorType > solver(matrix_operator,
                                            scalar_product,
                                            preconditioner,
                                            opts.get("precision", default_opts.get< S >("precision")),
                                            opts.get("max_iter", default_opts.get< size_t >("max_iter")),
#if HAVE_MPI
                                            (communicator_.communicator().rank() == 0)
                                            ? opts.get("verbose", default_opts.get< int >("verbose"))
                                            : 0
#else // HAVE_MPI
                                            opts.get("verbose", default_opts.get< int >("verbose"))
#endif
                                            );

    InverseOperatorResult stats;
    solver.apply(solution.backend(), rhs.backend(), stats);
    return stats;
  } // ... call(...)
protected:
  const MatrixType& matrix_;
  const CommunicatorType& communicator_;
};

//! specialization for our faux type \ref SequentialCommunication
template< class S >
class AmgApplicator< S, SequentialCommunication >
{
  typedef IstlRowMajorSparseMatrix< S >  MatrixType;
  typedef typename MatrixType::BackendType           IstlMatrixType;
  typedef typename IstlDenseVector< S >::BackendType IstlVectorType;

public:
  AmgApplicator(const MatrixType& matrix, const SequentialCommunication& comm)
    : matrix_(matrix)
    , communicator_(comm)
  {}

  InverseOperatorResult call(IstlDenseVector< S >& rhs,
                             IstlDenseVector< S >& solution,
                             const Common::ConfigContainer& opts,
                             const Common::ConfigContainer& default_opts)
  {
    typedef MatrixAdapter< IstlMatrixType, IstlVectorType, IstlVectorType > MatrixOperatorType;
    MatrixOperatorType matrix_operator(matrix_.backend());

    // define the scalar product
    Dune::SeqScalarProduct< typename IstlDenseVector< S >::BackendType > scalar_product;

    // define ILU0 as the smoother for the AMG

    typedef SeqILU0< IstlMatrixType, IstlVectorType, IstlVectorType > SmootherType;

    typename Amg::SmootherTraits< SmootherType >::Arguments smoother_parameters;
    smoother_parameters.iterations = opts.get("smoother.iterations",
                                              default_opts.get< int >("smoother.iterations"));
    smoother_parameters.relaxationFactor = opts.get("smoother.relaxation_factor",
                                                    default_opts.get< S >("smoother.relaxation_factor"));

    // define the AMG as the preconditioner for the BiCGStab solver
    Amg::Parameters amg_parameters(opts.get("preconditioner.max_level",
                                            default_opts.get< int >("preconditioner.max_level")),
                                   opts.get("preconditioner.coarse_target",
                                            default_opts.get< int >("preconditioner.coarse_target")),
                                   opts.get("preconditioner.min_coarse_rate",
                                            default_opts.get< S >("preconditioner.min_coarse_rate")),
                                   opts.get("preconditioner.prolong_damp",
                                            default_opts.get< S >("preconditioner.prolong_damp")));
    amg_parameters.setDefaultValuesIsotropic(opts.get("preconditioner.isotropy_dim",
                                                      default_opts.get< size_t >("preconditioner.isotropy_dim")));
    amg_parameters.setDefaultValuesAnisotropic(opts.get("preconditioner.anisotropy_dim",
                                                        default_opts.get< size_t >("preconditioner.anisotropy_dim")));
    amg_parameters.setDebugLevel(opts.get("preconditioner.verbose",
                                          default_opts.get< int >("preconditioner.verbose")));
    Amg::CoarsenCriterion< Amg::SymmetricCriterion< IstlMatrixType, Amg::FirstDiagonal > >
        amg_criterion(amg_parameters);

    typedef Amg::AMG< MatrixOperatorType, IstlVectorType, SmootherType > PreconditionerType;
    PreconditionerType preconditioner(matrix_operator, amg_criterion, smoother_parameters);

    // define the BiCGStab as the actual solver
    BiCGSTABSolver< IstlVectorType > solver(matrix_operator,
                                            scalar_product,
                                            preconditioner,
                                            opts.get("precision", default_opts.get< S >("precision")),
                                            opts.get("max_iter", default_opts.get< int >("max_iter")),
                                            opts.get("verbose", default_opts.get< int >("verbose")));
    InverseOperatorResult stats;
    solver.apply(solution.backend(), rhs.backend(), stats);
    return stats;
  } // ... call(...)

protected:
  const MatrixType& matrix_;
  const SequentialCommunication& communicator_;
};

#else //HAVE_DUNE_ISTL

template< class S, class T >
class AmgApplicator
{
  static_assert(Dune::AlwaysFalse< S >::value, "You are missing dune-istl!");
};

#endif //HAVE_DUNE_ISTL

} // namespace LA
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_LA_SOLVER_ISTL_AMG_HH
<|endoftext|>


<commit_before>/* Test access of fields on a ghosted mesh obtained via the workflow:
   APF -> omega_h -> ghost -> APF. This test assumes that the fields are
   real valued and that the mesh is 2d.
*/

#ifndef NOM3DC1
#define NOM3DC1
#endif

#include "m3dc1_ghost.h"
#include "m3dc1_mesh.h"
#include "m3dc1_model.h"
#include "apfOmega_h.h"
#include "m3dc1_scorec.h"
#include "m3dc1_mesh.h"
#include "gmi_mesh.h"
#include "gmi.h"
#include "gmi_null.h"
#include "apf.h"
#include "apfMDS.h"
#include "apfMesh2.h"
#include "PCU.h"
#include <cstdlib>
#include <iostream>
#include <assert.h>

using namespace std;

int main(int argc, char** argv)
{
  assert(argc == 3);
  MPI_Init(&argc, &argv);
  m3dc1_scorec_init();

  int op = 0, scalar_type = 0;
  int value_type[] = {scalar_type, scalar_type};
  int field_1 = 1, field_2 = 2, field_3 = 3;
  int num_values = 3, num_dofs = 6;
  int num_dofs_node = num_values * num_dofs;
  int num_vertex, num_own_vertex, vertex_dim = 0;
  int num_elem, elem_dim = 2;

  int num_plane = 1;

  if (argc < 2 && !PCU_Comm_Self()) {
    printf("Usage: ./ghost_example model mesh");
    return M3DC1_FAILURE;
  }

  m3dc1_model_load(argv[1]);
  m3dc1_mesh_load(argv[2]);
  m3dc1_mesh_getnument (&vertex_dim, &num_vertex);
  m3dc1_mesh_getnumownent (&vertex_dim, &num_own_vertex);
  m3dc1_mesh_getnument(&elem_dim, &num_elem);

  // Create and fill fields on APF mesh
  m3dc1_field_create(&field_1,
		     "field_1",
		     &num_values,
		     value_type,
		     &num_dofs);
  m3dc1_field_create(&field_2,
		     "field_2",
		     &num_values,
		     value_type,
		     &num_dofs);
  m3dc1_field_create(&field_3,
		     "field_3",
		     &num_values,
		     value_type,
		     &num_dofs);

  // fill field_1
  printf("\n");
  m3dc1_field_printcompnorm(&field_1, "field_1 init info");
  for(int inode=0; inode<num_vertex; inode++)
  {
    double xyz[3];
    m3dc1_node_getcoord(&inode, xyz);
    // 2D mesh, z-component = 0
    if(num_plane==1) assert(AlmostEqualDoubles(xyz[2], 0, 1e-6, 1e-6));
    vector<double> dofs(num_dofs_node*(1+scalar_type));
    for(int i=0; i<num_dofs_node*(1+scalar_type); i++)
      dofs.at(i)=xyz[i%3];
    m3dc1_ent_setdofdata(&vertex_dim, &inode, &field_1,
			 &num_dofs_node, &dofs.at(0));
  }
  m3dc1_field_printcompnorm(&field_1, "field_1 after set info");

  // fill field_2
  printf("\n");
  m3dc1_field_printcompnorm(&field_2, "field_2 init info");
  for(int inode=0; inode<num_vertex; inode++)
  {
    double xyz[3];
    m3dc1_node_getcoord(&inode, xyz);
    if(num_plane==1) assert(AlmostEqualDoubles(xyz[2], 0, 1e-6, 1e-6));
    vector<double> dofs(num_dofs_node*(1+scalar_type));
    for(int i=0; i<num_dofs_node*(1+scalar_type); i++)
      dofs.at(i)=xyz[i%5];
    m3dc1_ent_setdofdata(&vertex_dim, &inode, &field_2,
			 &num_dofs_node, &dofs.at(0));
  }
  m3dc1_field_printcompnorm(&field_2, "field_1 after set info");

  // fill field_3
  printf("\n");
  m3dc1_field_printcompnorm(&field_3, "field_3 init info");
  for(int inode=0; inode<num_vertex; inode++)
  {
    double xyz[3];
    m3dc1_node_getcoord(&inode, xyz);
    if(num_plane==1) assert(AlmostEqualDoubles(xyz[2], 0, 1e-6, 1e-6));
    vector<double> dofs(num_dofs_node*(1+scalar_type));
    for(int i=0; i<num_dofs_node*(1+scalar_type); i++)
      dofs.at(i)=xyz[i%7];
    m3dc1_ent_setdofdata(&vertex_dim, &inode, &field_3,
			 &num_dofs_node, &dofs.at(0));
  }
  m3dc1_field_printcompnorm(&field_3, "field_3 after set info");

  // Initialize ghosted mesh

  int nlayers = 1;
  m3dc1_ghost_load(&nlayers);

  // Check fields on ghosted mesh

  int exists_1, exists_2, exists_3;
  m3dc1_gfield_exist(&field_1, &exists_1);
  printf("\nField 1 on ghosted mesh exists: %d\n", exists_1);

  m3dc1_gfield_exist(&field_2, &exists_2);
  printf("\nField 2 on ghosted mesh exists: %d\n", exists_2);

  m3dc1_gfield_exist(&field_3, &exists_3);
  printf("\nField 3 on ghosted mesh exists: %d\n", exists_3);

  m3dc1_gfield_printcompnorm(&field_1, "field_1 on ghosted mesh");
  m3dc1_gfield_printcompnorm(&field_2, "field_2 on ghosted mesh");
  m3dc1_gfield_printcompnorm(&field_3, "field_3 on ghosted mesh");

  // Clean up and finalize
  m3dc1_field_delete(&field_1);
  m3dc1_field_delete(&field_2);
  m3dc1_field_delete(&field_3);

  m3dc1_scorec_finalize();
  MPI_Finalize();
  return M3DC1_SUCCESS;
}

<commit_msg>Updated: more field manipulation examples<commit_after>/* Test access of fields on a ghosted mesh obtained via the workflow:
   APF -> omega_h -> ghost -> APF. This test assumes that the fields are
   real valued and that the mesh is 2d.
*/

#ifndef NOM3DC1
#define NOM3DC1
#endif

#include "m3dc1_ghost.h"
#include "m3dc1_mesh.h"
#include "m3dc1_model.h"
#include "apfOmega_h.h"
#include "m3dc1_scorec.h"
#include "m3dc1_mesh.h"
#include "gmi_mesh.h"
#include "gmi.h"
#include "gmi_null.h"
#include "apf.h"
#include "apfMDS.h"
#include "apfMesh2.h"
#include "PCU.h"
#include <cstdlib>
#include <iostream>
#include <assert.h>

using namespace std;

int main(int argc, char** argv)
{
  assert(argc == 3);
  MPI_Init(&argc, &argv);
  m3dc1_scorec_init();

  int op = 0, scalar_type = 0;
  int value_type[] = {scalar_type, scalar_type};
  int field_1 = 1, field_2 = 2, field_3 = 3;
  int num_values = 3, num_dofs = 6;
  int num_dofs_node = num_values * num_dofs;
  int num_vertex, num_own_vertex, vertex_dim = 0;
  int num_elem, elem_dim = 2;

  int num_plane = 1;

  if (argc < 2 && !PCU_Comm_Self()) {
    printf("Usage: ./ghost_example model mesh");
    return M3DC1_FAILURE;
  }

  m3dc1_model_load(argv[1]);
  m3dc1_mesh_load(argv[2]);
  m3dc1_mesh_getnument (&vertex_dim, &num_vertex);
  m3dc1_mesh_getnumownent (&vertex_dim, &num_own_vertex);
  m3dc1_mesh_getnument(&elem_dim, &num_elem);

  // Create and fill fields on APF mesh
  m3dc1_field_create(&field_1,
		     "field_1",
		     &num_values,
		     value_type,
		     &num_dofs);
  m3dc1_field_create(&field_2,
		     "field_2",
		     &num_values,
		     value_type,
		     &num_dofs);
  m3dc1_field_create(&field_3,
		     "field_3",
		     &num_values,
		     value_type,
		     &num_dofs);

  // fill field_1
  printf("\n");
  m3dc1_field_printcompnorm(&field_1, "field_1 init info");
  for(int inode=0; inode<num_vertex; inode++)
  {
    double xyz[3];
    m3dc1_node_getcoord(&inode, xyz);
    // 2D mesh, z-component = 0
    if(num_plane==1) assert(AlmostEqualDoubles(xyz[2], 0, 1e-6, 1e-6));
    vector<double> dofs(num_dofs_node*(1+scalar_type));
    for(int i=0; i<num_dofs_node*(1+scalar_type); i++)
      dofs.at(i)=xyz[i%3];
    m3dc1_ent_setdofdata(&vertex_dim, &inode, &field_1,
			 &num_dofs_node, &dofs.at(0));
  }
  m3dc1_field_printcompnorm(&field_1, "field_1 after set info");

  // fill field_2
  printf("\n");
  m3dc1_field_printcompnorm(&field_2, "field_2 init info");
  for(int inode=0; inode<num_vertex; inode++)
  {
    double xyz[3];
    m3dc1_node_getcoord(&inode, xyz);
    if(num_plane==1) assert(AlmostEqualDoubles(xyz[2], 0, 1e-6, 1e-6));
    vector<double> dofs(num_dofs_node*(1+scalar_type));
    for(int i=0; i<num_dofs_node*(1+scalar_type); i++)
      dofs.at(i)=xyz[i%5];
    m3dc1_ent_setdofdata(&vertex_dim, &inode, &field_2,
			 &num_dofs_node, &dofs.at(0));
  }
  m3dc1_field_printcompnorm(&field_2, "field_2 after set info");

  // fill field_3
  printf("\n");
  m3dc1_field_printcompnorm(&field_3, "field_3 init info");
  for(int inode=0; inode<num_vertex; inode++)
  {
    double xyz[3];
    m3dc1_node_getcoord(&inode, xyz);
    if(num_plane==1) assert(AlmostEqualDoubles(xyz[2], 0, 1e-6, 1e-6));
    vector<double> dofs(num_dofs_node*(1+scalar_type));
    for(int i=0; i<num_dofs_node*(1+scalar_type); i++)
      dofs.at(i)=xyz[i%7];
    m3dc1_ent_setdofdata(&vertex_dim, &inode, &field_3,
			 &num_dofs_node, &dofs.at(0));
  }
  m3dc1_field_printcompnorm(&field_3, "field_3 after set info");

  // Initialize ghosted mesh

  int nlayers = 1;
  m3dc1_ghost_load(&nlayers);

  // Check fields exist on ghosted mesh

  int exists_1, exists_2, exists_3;
  m3dc1_gfield_exist(&field_1, &exists_1);
  printf("\nField 1 on ghosted mesh exists: %d", exists_1);

  m3dc1_gfield_exist(&field_2, &exists_2);
  printf("\nField 2 on ghosted mesh exists: %d", exists_2);

  m3dc1_gfield_exist(&field_3, &exists_3);
  printf("\nField 3 on ghosted mesh exists: %d\n", exists_3);

  // Compute the norms of the fields on the ghosted_mesh
  printf("\n");
  m3dc1_gfield_printcompnorm(&field_1, "field_1 on ghosted mesh");
  m3dc1_gfield_printcompnorm(&field_2, "field_2 on ghosted mesh");
  m3dc1_gfield_printcompnorm(&field_3, "field_3 on ghosted mesh");

  // Scale field 1 on the ghosted by a constant and check norm again
  double factor = 2.0;
  printf("\nfield_1 scaled by %1.1f\n", factor);
  m3dc1_gfield_mult(&field_1, &factor, &scalar_type);
  m3dc1_gfield_printcompnorm(&field_1, "scaled field_1 on ghosted mesh");

  // Add field_2 and field_3 and store result on field_2
  m3dc1_gfield_add(&field_2, &field_3);
  printf("\nAdded field_3 to field_2.\n");
  m3dc1_gfield_printcompnorm(&field_2, "Updated field_2 on ghosted mesh");

  // Clean up and finalize
  m3dc1_field_delete(&field_1);
  m3dc1_field_delete(&field_2);
  m3dc1_field_delete(&field_3);

  m3dc1_scorec_finalize();
  MPI_Finalize();
  return M3DC1_SUCCESS;
}

<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

// Base class for generators using external MC generators.
// For example AliGenPythia using Pythia.
// Provides basic functionality: setting of kinematic cuts on
// decay products and particle selection.
// andreas.morsch@cern.ch

#include <TClonesArray.h>
#include <TMath.h>
#include <TPDGCode.h>
#include <TParticle.h>

#include "AliGenMC.h"
#include "AliRun.h"
#include "AliGeometry.h"

ClassImp(AliGenMC)

AliGenMC::AliGenMC()
    :AliGenerator(),
     fParticles("TParticle", 1000),
     fParentSelect(8),
     fChildSelect(8),
     fCutOnChild(0),
     fChildPtMin(0.),
     fChildPtMax(1.e10),
     fChildPMin(0.),
     fChildPMax(1.e10),
     fChildPhiMin(0.),
     fChildPhiMax(2. * TMath::Pi()),
     fChildThetaMin(0.),
     fChildThetaMax(TMath::Pi()),
     fChildYMin(-12.),
     fChildYMax(12.),
     fXingAngleX(0.),
     fXingAngleY(0.),
     fForceDecay(kAll),
     fMaxLifeTime(1.e-15),
     fDyBoost(0.),
     fGeometryAcceptance(0),
     fPdgCodeParticleforAcceptanceCut(0),
     fNumberOfAcceptedParticles(0),
     fNprimaries(0)
{
// Default Constructor
  fAProjectile = 1;
  fZProjectile = 1;
  fATarget = 1;
  fZTarget = 1;
  fProjectile = "P";
  fTarget = "P";
}

AliGenMC::AliGenMC(Int_t npart)
    :AliGenerator(npart),
     fParticles("TParticle", 1000),
     fParentSelect(8),
     fChildSelect(8),
     fCutOnChild(0),
     fChildPtMin(0.),
     fChildPtMax(1.e10),
     fChildPMin(0.),
     fChildPMax(1.e10),
     fChildPhiMin(0.),
     fChildPhiMax(2. * TMath::Pi()),
     fChildThetaMin(0.),
     fChildThetaMax(TMath::Pi()),
     fChildYMin(-12.),
     fChildYMax(12.),
     fXingAngleX(0.),
     fXingAngleY(0.),
     fForceDecay(kAll),
     fMaxLifeTime(1.e-15),
     fDyBoost(0.),
     fGeometryAcceptance(0),
     fPdgCodeParticleforAcceptanceCut(0),
     fNumberOfAcceptedParticles(0),
     fNprimaries(0)
{
//  Constructor
//
  fAProjectile = 1;
  fZProjectile = 1;
  fATarget = 1;
  fZTarget = 1;
  fProjectile = "P";
  fTarget = "P";
  for (Int_t i=0; i<8; i++) fParentSelect[i]=fChildSelect[i]=0;
}

AliGenMC::~AliGenMC()
{
// Destructor
}

void AliGenMC::Init()
{
//
//  Initialization
    switch (fForceDecay) {
    case kBSemiElectronic:
    case kSemiElectronic:
    case kDiElectron:
    case kBJpsiDiElectron:
    case kBPsiPrimeDiElectron:
	fChildSelect[0] = kElectron;
	break;
    case kHardMuons:
    case kBSemiMuonic:
    case kSemiMuonic:
    case kDiMuon:
    case kBJpsiDiMuon:
    case kBPsiPrimeDiMuon:
    case kPiToMu:
    case kKaToMu:
    case kWToMuon:
    case kWToCharmToMuon:
    case kZDiMuon:
    case kZDiElectron:
	fChildSelect[0]=kMuonMinus;
	break;
    case kWToCharm:
	break;
    case kHadronicD:
    case kHadronicDWithout4Bodies:
	fChildSelect[0]=kPiPlus;
	fChildSelect[1]=kKPlus;
	break;
    case kPhiKK:
	fChildSelect[0]=kKPlus;
	break;
    case kBJpsi:
	fChildSelect[0]= 443;
	break;
   case kChiToJpsiGammaToMuonMuon:
        fChildSelect[0]= 22;
        fChildSelect[1]= 13;
        break;
    case kChiToJpsiGammaToElectronElectron:
        fChildSelect[0]= 22;
        fChildSelect[1]= 11;
        break;

    case kOmega:
    case kAll:
    case kAllMuonic:
    case kNoDecay:
    case kNoDecayHeavy:
    case kNeutralPion:
	break;
    }

    if (fZTarget != 0 && fAProjectile != 0)
    {
	fDyBoost    = - 0.5 * TMath::Log(Double_t(fZProjectile) * Double_t(fATarget) /
					 (Double_t(fZTarget)    * Double_t(fAProjectile)));
    }
}

Bool_t AliGenMC::ParentSelected(Int_t ip) const
{
// True if particle is in list of parent particles to be selected
    for (Int_t i=0; i<8; i++)
    {
	if (fParentSelect.At(i) == ip) return kTRUE;
    }
    return kFALSE;
}

Bool_t AliGenMC::ChildSelected(Int_t ip) const
{
// True if particle is in list of decay products to be selected
    for (Int_t i=0; i<5; i++)
    {
	if (fChildSelect.At(i) == ip) return kTRUE;
    }
    return kFALSE;
}

Bool_t AliGenMC::KinematicSelection(TParticle *particle, Int_t flag) const
{
// Perform kinematic selection
    Double_t pz    = particle->Pz();
    Double_t  e    = particle->Energy();
    Double_t pt    = particle->Pt();
    Double_t p     = particle->P();
    Double_t theta = particle->Theta();
    Double_t mass  = particle->GetCalcMass();
    Double_t mt2   = pt * pt + mass * mass;
    Double_t phi   = particle->Phi();

    Double_t y, y0;

    if (TMath::Abs(pz) <  e) {
	y = 0.5*TMath::Log((e+pz)/(e-pz));
    } else {
	y = 1.e10;
    }

    if (mt2) {
	y0 = 0.5*TMath::Log((e+TMath::Abs(pz))*(e+TMath::Abs(pz))/mt2);
    } else {
	if (TMath::Abs(y) < 1.e10) {
	    y0 = y;
	} else {
	    y0 = 1.e10;
	}
    }

    y = (pz < 0) ? -y0 : y0;

    if (flag == 0) {
//
// Primary particle cuts
//
//  transverse momentum cut
	if (pt > fPtMax || pt < fPtMin) {
//	    printf("\n failed pt cut %f %f %f \n",pt,fPtMin,fPtMax);
	    return kFALSE;
	}
//
// momentum cut
	if (p > fPMax || p < fPMin) {
//	    printf("\n failed p cut %f %f %f \n",p,fPMin,fPMax);
	    return kFALSE;
	}
//
// theta cut
	if (theta > fThetaMax || theta < fThetaMin) {
//	    printf("\n failed theta cut %f %f %f \n",theta,fThetaMin,fThetaMax);
	    return kFALSE;
	}
//
// rapidity cut
	if (y > fYMax || y < fYMin) {
//	    printf("\n failed y cut %f %f %f \n",y,fYMin,fYMax);
	    return kFALSE;
	}
//
// phi cut
	if (phi > fPhiMax || phi < fPhiMin) {
//	    printf("\n failed phi cut %f %f %f \n",phi,fPhiMin,fPhiMax);
	    return kFALSE;
	}
    } else {
//
// Decay product cuts
//
//  transverse momentum cut
	if (pt > fChildPtMax || pt < fChildPtMin) {
//	    printf("\n failed pt cut %f %f %f \n",pt,fChildPtMin,fChildPtMax);
	    return kFALSE;
	}
//
// momentum cut
	if (p > fChildPMax || p < fChildPMin) {
//	    printf("\n failed p cut %f %f %f \n",p,fChildPMin,fChildPMax);
	    return kFALSE;
	}
//
// theta cut
	if (theta > fChildThetaMax || theta < fChildThetaMin) {
//	    printf("\n failed theta cut %f %f %f \n",theta,fChildThetaMin,fChildThetaMax);
	    return kFALSE;
	}
//
// rapidity cut
	if (y > fChildYMax || y < fChildYMin) {
//	    printf("\n failed y cut %f %f %f \n",y,fChildYMin,fChildYMax);
	    return kFALSE;
	}
//
// phi cut
	if (phi > fChildPhiMax || phi < fChildPhiMin) {
//	    printf("\n failed phi cut %f %f %f \n",phi,fChildPhiMin,fChildPhiMax);
	    return kFALSE;
	}
    }

    return kTRUE;
}

Bool_t AliGenMC::CheckAcceptanceGeometry(Int_t np, TClonesArray* particles)
{
// Check the geometrical acceptance for particle.

  Bool_t check ;
  Int_t numberOfPdgCodeParticleforAcceptanceCut = 0;
  Int_t numberOfAcceptedPdgCodeParticleforAcceptanceCut = 0;
  TParticle * particle;
  Int_t i;
  for (i = 0; i < np; i++) {
    particle =  (TParticle *) particles->At(i);
    if( TMath::Abs( particle->GetPdgCode() ) == TMath::Abs( fPdgCodeParticleforAcceptanceCut ) ) {
      numberOfPdgCodeParticleforAcceptanceCut++;
      if (fGeometryAcceptance->Impact(particle)) numberOfAcceptedPdgCodeParticleforAcceptanceCut++;
    }
  }
  if ( numberOfAcceptedPdgCodeParticleforAcceptanceCut > (fNumberOfAcceptedParticles-1) )
    check = kTRUE;
  else
    check = kFALSE;

  return check;
}

Int_t AliGenMC::CheckPDGCode(Int_t pdgcode) const
{
//
//  If the particle is in a diffractive state, then take action accordingly
  switch (pdgcode) {
  case 91:
    return 92;
  case 110:
    //rho_diff0 -- difficult to translate, return rho0
    return 113;
  case 210:
    //pi_diffr+ -- change to pi+
    return 211;
  case 220:
    //omega_di0 -- change to omega0
    return 223;
  case 330:
    //phi_diff0 -- return phi0
    return 333;
  case 440:
    //J/psi_di0 -- return J/psi
    return 443;
  case 2110:
    //n_diffr -- return neutron
    return 2112;
  case 2210:
    //p_diffr+ -- return proton
    return 2212;
  }
  //non diffractive state -- return code unchanged
  return pdgcode;
}

void AliGenMC::Boost()
{
//
// Boost cms into LHC lab frame
//

    Double_t beta  = TMath::TanH(fDyBoost);
    Double_t gamma = 1./TMath::Sqrt((1.-beta)*(1.+beta));
    Double_t gb    = gamma * beta;

    //    printf("\n Boosting particles to lab frame %f %f %f", fDyBoost, beta, gamma);

    Int_t i;
    Int_t np = fParticles.GetEntriesFast();
    for (i = 0; i < np; i++)
    {
	TParticle* iparticle = (TParticle*) fParticles.At(i);

	Double_t e   = iparticle->Energy();
	Double_t px  = iparticle->Px();
	Double_t py  = iparticle->Py();
	Double_t pz  = iparticle->Pz();

	Double_t eb  = gamma * e -      gb * pz;
	Double_t pzb =   -gb * e +   gamma * pz;

	iparticle->SetMomentum(px, py, pzb, eb);
    }
}

void AliGenMC::AddHeader(AliGenEventHeader* header)
{
    // Passes header either to the container or to gAlice
    if (fContainer) {
	fContainer->AddHeader(header);
    } else {
	gAlice->SetGenEventHeader(header);
    }
}
<commit_msg>Protection added.<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

// Base class for generators using external MC generators.
// For example AliGenPythia using Pythia.
// Provides basic functionality: setting of kinematic cuts on
// decay products and particle selection.
// andreas.morsch@cern.ch

#include <TClonesArray.h>
#include <TMath.h>
#include <TPDGCode.h>
#include <TParticle.h>

#include "AliGenMC.h"
#include "AliRun.h"
#include "AliGeometry.h"

ClassImp(AliGenMC)

AliGenMC::AliGenMC()
    :AliGenerator(),
     fParticles("TParticle", 1000),
     fParentSelect(8),
     fChildSelect(8),
     fCutOnChild(0),
     fChildPtMin(0.),
     fChildPtMax(1.e10),
     fChildPMin(0.),
     fChildPMax(1.e10),
     fChildPhiMin(0.),
     fChildPhiMax(2. * TMath::Pi()),
     fChildThetaMin(0.),
     fChildThetaMax(TMath::Pi()),
     fChildYMin(-12.),
     fChildYMax(12.),
     fXingAngleX(0.),
     fXingAngleY(0.),
     fForceDecay(kAll),
     fMaxLifeTime(1.e-15),
     fDyBoost(0.),
     fGeometryAcceptance(0),
     fPdgCodeParticleforAcceptanceCut(0),
     fNumberOfAcceptedParticles(0),
     fNprimaries(0)
{
// Default Constructor
  fAProjectile = 1;
  fZProjectile = 1;
  fATarget = 1;
  fZTarget = 1;
  fProjectile = "P";
  fTarget = "P";
}

AliGenMC::AliGenMC(Int_t npart)
    :AliGenerator(npart),
     fParticles("TParticle", 1000),
     fParentSelect(8),
     fChildSelect(8),
     fCutOnChild(0),
     fChildPtMin(0.),
     fChildPtMax(1.e10),
     fChildPMin(0.),
     fChildPMax(1.e10),
     fChildPhiMin(0.),
     fChildPhiMax(2. * TMath::Pi()),
     fChildThetaMin(0.),
     fChildThetaMax(TMath::Pi()),
     fChildYMin(-12.),
     fChildYMax(12.),
     fXingAngleX(0.),
     fXingAngleY(0.),
     fForceDecay(kAll),
     fMaxLifeTime(1.e-15),
     fDyBoost(0.),
     fGeometryAcceptance(0),
     fPdgCodeParticleforAcceptanceCut(0),
     fNumberOfAcceptedParticles(0),
     fNprimaries(0)
{
//  Constructor
//
  fAProjectile = 1;
  fZProjectile = 1;
  fATarget = 1;
  fZTarget = 1;
  fProjectile = "P";
  fTarget = "P";
  for (Int_t i=0; i<8; i++) fParentSelect[i]=fChildSelect[i]=0;
}

AliGenMC::~AliGenMC()
{
// Destructor
}

void AliGenMC::Init()
{
//
//  Initialization
    switch (fForceDecay) {
    case kBSemiElectronic:
    case kSemiElectronic:
    case kDiElectron:
    case kBJpsiDiElectron:
    case kBPsiPrimeDiElectron:
	fChildSelect[0] = kElectron;
	break;
    case kHardMuons:
    case kBSemiMuonic:
    case kSemiMuonic:
    case kDiMuon:
    case kBJpsiDiMuon:
    case kBPsiPrimeDiMuon:
    case kPiToMu:
    case kKaToMu:
    case kWToMuon:
    case kWToCharmToMuon:
    case kZDiMuon:
    case kZDiElectron:
	fChildSelect[0]=kMuonMinus;
	break;
    case kWToCharm:
	break;
    case kHadronicD:
    case kHadronicDWithout4Bodies:
	fChildSelect[0]=kPiPlus;
	fChildSelect[1]=kKPlus;
	break;
    case kPhiKK:
	fChildSelect[0]=kKPlus;
	break;
    case kBJpsi:
	fChildSelect[0]= 443;
	break;
   case kChiToJpsiGammaToMuonMuon:
        fChildSelect[0]= 22;
        fChildSelect[1]= 13;
        break;
    case kChiToJpsiGammaToElectronElectron:
        fChildSelect[0]= 22;
        fChildSelect[1]= 11;
        break;

    case kOmega:
    case kAll:
    case kAllMuonic:
    case kNoDecay:
    case kNoDecayHeavy:
    case kNeutralPion:
	break;
    }

    if (fZTarget != 0 && fAProjectile != 0)
    {
	fDyBoost    = - 0.5 * TMath::Log(Double_t(fZProjectile) * Double_t(fATarget) /
					 (Double_t(fZTarget)    * Double_t(fAProjectile)));
    }
}

Bool_t AliGenMC::ParentSelected(Int_t ip) const
{
// True if particle is in list of parent particles to be selected
    for (Int_t i=0; i<8; i++)
    {
	if (fParentSelect.At(i) == ip) return kTRUE;
    }
    return kFALSE;
}

Bool_t AliGenMC::ChildSelected(Int_t ip) const
{
// True if particle is in list of decay products to be selected
    for (Int_t i=0; i<5; i++)
    {
	if (fChildSelect.At(i) == ip) return kTRUE;
    }
    return kFALSE;
}

Bool_t AliGenMC::KinematicSelection(TParticle *particle, Int_t flag) const
{
// Perform kinematic selection
    Double_t pz    = particle->Pz();
    Double_t pt    = particle->Pt();
    Double_t p     = particle->P();
    Double_t theta = particle->Theta();
    Double_t mass  = particle->GetCalcMass();
    Double_t mt2   = pt * pt + mass * mass;
    Double_t phi   = particle->Phi();
    Double_t e     = particle->Energy();

    if (e == 0.)
	e = TMath::Sqrt(p * p + mass * mass);

    Double_t y, y0;

    if (TMath::Abs(pz) <  e) {
	y = 0.5*TMath::Log((e+pz)/(e-pz));
    } else {
	y = 1.e10;
    }

    if (mt2) {
	y0 = 0.5*TMath::Log((e+TMath::Abs(pz))*(e+TMath::Abs(pz))/mt2);
    } else {
	if (TMath::Abs(y) < 1.e10) {
	    y0 = y;
	} else {
	    y0 = 1.e10;
	}
    }

    y = (pz < 0) ? -y0 : y0;

    if (flag == 0) {
//
// Primary particle cuts
//
//  transverse momentum cut
	if (pt > fPtMax || pt < fPtMin) {
//	    printf("\n failed pt cut %f %f %f \n",pt,fPtMin,fPtMax);
	    return kFALSE;
	}
//
// momentum cut
	if (p > fPMax || p < fPMin) {
//	    printf("\n failed p cut %f %f %f \n",p,fPMin,fPMax);
	    return kFALSE;
	}
//
// theta cut
	if (theta > fThetaMax || theta < fThetaMin) {
//	    printf("\n failed theta cut %f %f %f \n",theta,fThetaMin,fThetaMax);
	    return kFALSE;
	}
//
// rapidity cut
	if (y > fYMax || y < fYMin) {
//	    printf("\n failed y cut %f %f %f \n",y,fYMin,fYMax);
	    return kFALSE;
	}
//
// phi cut
	if (phi > fPhiMax || phi < fPhiMin) {
//	    printf("\n failed phi cut %f %f %f \n",phi,fPhiMin,fPhiMax);
	    return kFALSE;
	}
    } else {
//
// Decay product cuts
//
//  transverse momentum cut
	if (pt > fChildPtMax || pt < fChildPtMin) {
//	    printf("\n failed pt cut %f %f %f \n",pt,fChildPtMin,fChildPtMax);
	    return kFALSE;
	}
//
// momentum cut
	if (p > fChildPMax || p < fChildPMin) {
//	    printf("\n failed p cut %f %f %f \n",p,fChildPMin,fChildPMax);
	    return kFALSE;
	}
//
// theta cut
	if (theta > fChildThetaMax || theta < fChildThetaMin) {
//	    printf("\n failed theta cut %f %f %f \n",theta,fChildThetaMin,fChildThetaMax);
	    return kFALSE;
	}
//
// rapidity cut
	if (y > fChildYMax || y < fChildYMin) {
//	    printf("\n failed y cut %f %f %f \n",y,fChildYMin,fChildYMax);
	    return kFALSE;
	}
//
// phi cut
	if (phi > fChildPhiMax || phi < fChildPhiMin) {
//	    printf("\n failed phi cut %f %f %f \n",phi,fChildPhiMin,fChildPhiMax);
	    return kFALSE;
	}
    }

    return kTRUE;
}

Bool_t AliGenMC::CheckAcceptanceGeometry(Int_t np, TClonesArray* particles)
{
// Check the geometrical acceptance for particle.

  Bool_t check ;
  Int_t numberOfPdgCodeParticleforAcceptanceCut = 0;
  Int_t numberOfAcceptedPdgCodeParticleforAcceptanceCut = 0;
  TParticle * particle;
  Int_t i;
  for (i = 0; i < np; i++) {
    particle =  (TParticle *) particles->At(i);
    if( TMath::Abs( particle->GetPdgCode() ) == TMath::Abs( fPdgCodeParticleforAcceptanceCut ) ) {
      numberOfPdgCodeParticleforAcceptanceCut++;
      if (fGeometryAcceptance->Impact(particle)) numberOfAcceptedPdgCodeParticleforAcceptanceCut++;
    }
  }
  if ( numberOfAcceptedPdgCodeParticleforAcceptanceCut > (fNumberOfAcceptedParticles-1) )
    check = kTRUE;
  else
    check = kFALSE;

  return check;
}

Int_t AliGenMC::CheckPDGCode(Int_t pdgcode) const
{
//
//  If the particle is in a diffractive state, then take action accordingly
  switch (pdgcode) {
  case 91:
    return 92;
  case 110:
    //rho_diff0 -- difficult to translate, return rho0
    return 113;
  case 210:
    //pi_diffr+ -- change to pi+
    return 211;
  case 220:
    //omega_di0 -- change to omega0
    return 223;
  case 330:
    //phi_diff0 -- return phi0
    return 333;
  case 440:
    //J/psi_di0 -- return J/psi
    return 443;
  case 2110:
    //n_diffr -- return neutron
    return 2112;
  case 2210:
    //p_diffr+ -- return proton
    return 2212;
  }
  //non diffractive state -- return code unchanged
  return pdgcode;
}

void AliGenMC::Boost()
{
//
// Boost cms into LHC lab frame
//

    Double_t beta  = TMath::TanH(fDyBoost);
    Double_t gamma = 1./TMath::Sqrt((1.-beta)*(1.+beta));
    Double_t gb    = gamma * beta;

    //    printf("\n Boosting particles to lab frame %f %f %f", fDyBoost, beta, gamma);

    Int_t i;
    Int_t np = fParticles.GetEntriesFast();
    for (i = 0; i < np; i++)
    {
	TParticle* iparticle = (TParticle*) fParticles.At(i);

	Double_t e   = iparticle->Energy();
	Double_t px  = iparticle->Px();
	Double_t py  = iparticle->Py();
	Double_t pz  = iparticle->Pz();

	Double_t eb  = gamma * e -      gb * pz;
	Double_t pzb =   -gb * e +   gamma * pz;

	iparticle->SetMomentum(px, py, pzb, eb);
    }
}

void AliGenMC::AddHeader(AliGenEventHeader* header)
{
    // Passes header either to the container or to gAlice
    if (fContainer) {
	fContainer->AddHeader(header);
    } else {
	gAlice->SetGenEventHeader(header);
    }
}
<|endoftext|>