<commit_before>//$Id$

#include "HopsanCore.h"
#include "GUIComponent.h"
#include <iostream>
#include "GUIPort.h"
#include "GUIConnector.h"
#include <ostream>
#include <assert.h>
#include <QDebug>

#include <QGraphicsWidget>
#include <QGraphicsSvgItem>
#include <QGraphicsTextItem>
#include <QWidget>
#include <QGraphicsView>
#include <vector>
#include <QGraphicsItem>

#include <QGraphicsSceneMoveEvent>

#include <math.h>
#include "ParameterDialog.h"

GUIComponent::GUIComponent(HopsanEssentials *hopsan, QStringList parameterData, QPoint position, GraphicsScene *scene, QGraphicsItem *parent)
        : QGraphicsWidget(parent)
{
    mpParentGraphicsScene = scene;
    mpParentGraphicsScene->addItem(this);
    mpParentGraphicsView = mpParentGraphicsScene->mpParentProjectTab->mpGraphicsView;

    mTextOffset = 1.1;

    QString componentTypeName = parameterData.at(0);
    QString fileName = parameterData.at(1);
    size_t nPorts = parameterData.at(2).toInt();

    //Core interaction
    mpCoreComponent = hopsan->CreateComponent(componentTypeName.toStdString());
    //

    setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemSendsGeometryChanges | QGraphicsItem::ItemUsesExtendedStyleOption);
    setFocusPolicy(Qt::ClickFocus);
    this->setAcceptHoverEvents(true);

    this->setZValue(10);
    mpIcon = new QGraphicsSvgItem(fileName,this);

    std::cout << "GUIcomponent: " << "x=" << this->pos().x() << "  " << "y=" << this->pos().y() << std::endl;
    std::cout << "GUIcomponent: " << componentTypeName.toStdString() << std::endl;

    setGeometry(0,0,mpIcon->boundingRect().width(),mpIcon->boundingRect().height());

    mpNameText = new GUIComponentNameTextItem(this);
    refreshName(); //Make sure name window is correct size for center positioning
    mpNameText->setPos(QPointF(mpIcon->boundingRect().width()/2-mpNameText->boundingRect().width()/2, mTextOffset*mpIcon->boundingRect().height()));

    //Sets the ports
    for (size_t i = 0; i < nPorts; ++i)
    {
        double x = parameterData.at(3+3*i).toDouble();
        double y = parameterData.at(4+3*i).toDouble();
        double rot = parameterData.at(5+3*i).toDouble();

        QString iconPath("../../HopsanGUI/porticons/");
        if (mpCoreComponent->getPortPtrVector().at(i)->getNodeType() == "NodeSignal")
        {
            iconPath.append("SignalPort");
            if (mpCoreComponent->getPortPtrVector().at(i)->getPortType() == "ReadPort")
                iconPath.append("_read");
            else
                iconPath.append("_write");
        }
        else if (mpCoreComponent->getPortPtrVector().at(i)->getNodeType() == "NodeMechanic")
        {
            iconPath.append("MechanicPort");
            if (mpCoreComponent->getTypeCQS() == "C")
                iconPath.append("C");
            else if (mpCoreComponent->getTypeCQS() == "Q")
                iconPath.append("Q");
        }
        else if (mpCoreComponent->getPortPtrVector().at(i)->getNodeType() == "NodeHydraulic")
        {
            iconPath.append("HydraulicPort");
            if (mpCoreComponent->getTypeCQS() == "C")
                iconPath.append("C");
            else if (mpCoreComponent->getTypeCQS() == "Q")
                iconPath.append("Q");
        }
        else
        {
            assert(false);
        }
        iconPath.append(".svg");

        mPortListPtrs.append(new GUIPort(mpCoreComponent->getPortPtrVector().at(i), x*mpIcon->sceneBoundingRect().width(),y*mpIcon->sceneBoundingRect().height(),rot,iconPath,this));//mpIcon));

    }

    connect(mpNameText, SIGNAL(textMoved(QPointF)), SLOT(fixTextPosition(QPointF)));
    //connect(this->mpParentGraphicsView,SIGNAL(keyPressDelete()),this,SLOT(deleteComponent()));

    setPos(position-QPoint(mpIcon->boundingRect().width()/2, mpIcon->boundingRect().height()/2));

    mpSelectionBox = new GUIComponentSelectionBox(0,0,mpIcon->boundingRect().width(),mpIcon->boundingRect().height(),
                                                  QPen(QColor("red"),3), QPen(QColor("darkRed"),2),this);
    mpSelectionBox->setVisible(false);
}

//GUIComponent::GUIComponent(HopsanEssentials *hopsan, const QString &fileName, QString componentTypeName, QPoint position, QGraphicsView *parentView, QGraphicsItem *parent)
//        : QGraphicsWidget(parent)
//{
//    //Core interaction
//    mpCoreComponent = hopsan->CreateComponent(componentTypeName.toStdString());
//    //
//
//    setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemSendsGeometryChanges | QGraphicsItem::ItemUsesExtendedStyleOption);
//    this->setAcceptHoverEvents(true);
//
//    //widget = new QWidget;
//
//    mpParentView = parentView;
//
//    this->setZValue(10);
//    icon = new QGraphicsSvgItem(fileName,this);
////    icon->setPos(QPointF(-icon->boundingRect().width()/2, -icon->boundingRect().height()/2));
//    std::cout << "GUIcomponent: " << "x=" << this->pos().x() << "  " << "y=" << this->pos().y() << std::endl;
//    std::cout << "GUIcomponent: " << componentTypeName.toStdString() << std::endl;
//
//    //setWindowFlags(Qt::SplashScreen);//just to see the geometry
//    setGeometry(0,0,icon->boundingRect().width(),icon->boundingRect().height());
//
//    mpNameText = new GUIComponentNameTextItem(mpCoreComponent, this);
//    mpNameText->setPos(QPointF(icon->boundingRect().width()/2-mpNameText->boundingRect().width()/2, icon->boundingRect().height()));
//
//    //UGLY UGLY HARD CODED PORT CONNECTION TO CORE...
//    mPortListPtrs.append(new GUIPort(mpCoreComponent->getPortPtrVector().at(0), icon->sceneBoundingRect().width()-5,icon->sceneBoundingRect().height()/2-5,10.0,10.0,this->getParentView(),this,icon));
//    mPortListPtrs.append(new GUIPort(mpCoreComponent->getPortPtrVector().at(1),-5,icon->sceneBoundingRect().height()/2-5,10.0,10.0,this->getParentView(),this,icon));
//
//    this->showPorts(false);
//
//    //icon->setPos(QPointF(-icon->boundingRect().width()/2, -icon->boundingRect().height()/2));
//
//   // rectR->boundingRegion();
//
//    connect(mpNameText, SIGNAL(textMoved(QPointF)), SLOT(fixTextPosition(QPointF)));
//    connect(this->mpParentView,SIGNAL(keyPressDelete()),this,SLOT(deleteComponent()));
//
//    setPos(position-QPoint(icon->boundingRect().width()/2, icon->boundingRect().height()/2));
//
//    mpSelectionBox = new GUIComponentSelectionBox(0,0,icon->boundingRect().width(),icon->boundingRect().height(),
//                                                  QPen(QColor("red"),3), QPen(QColor("darkRed"),2),this);
//    mpSelectionBox->setVisible(false);
//}

double dist(double x1,double y1, double x2, double y2)
{
    return sqrt(pow(x2-x1,2) + pow(y2-y1,2));
}

void GUIComponent::fixTextPosition(QPointF pos)
{
    double x1 = mpIcon->boundingRect().width()/2-mpNameText->boundingRect().width()/2;
    double y1 = mTextOffset*mpIcon->boundingRect().height();

    double x2 = mpIcon->boundingRect().width()/2-mpNameText->boundingRect().width()/2;
    double y2 = -mTextOffset*mpNameText->boundingRect().height();

    double x = mpNameText->mapToParent(pos).x();
    double y = mpNameText->mapToParent(pos).y();

    if (dist(x,y, x1,y1) > dist(x,y, x2,y2))
    {
        mpNameText->setPos(x2,y2);
    }
    else
    {
        mpNameText->setPos(x1,y1);
    }

    std::cout << "GUIComponent::fixTextPosition, x: " << x << " y: " << y << std::endl;

}

void GUIComponent::mouseReleaseEvent ( QGraphicsSceneMouseEvent * event )
{
    qDebug() << "GUIComponent: " << "mouseReleaseEvent";
    QGraphicsItem::mouseReleaseEvent(event);
}

GUIComponent::~GUIComponent()
{
    //delete widget;
}

//QGraphicsView *GUIComponent::getParentView()
//{
//    return mpParentView;
//}

void GUIComponent::addConnector(GUIConnector *item)
{
    connect(this,SIGNAL(componentMoved()),item,SLOT(updatePos()));
}

//! This function refreshes the displayed name (HopsanCore may have changed it)
void GUIComponent::refreshName()
{
    mpNameText->setPlainText(getName());
    //Adjust the position of the text
}

//! This function returns the current component name
QString GUIComponent::getName()
{
    return QString::fromStdString(mpCoreComponent->getName());
}

//! This function sets the desired component name
void GUIComponent::setName(QString name)
{
    mpCoreComponent->setName(name.toStdString());
    refreshName();
}

GUIPort *GUIComponent::getPort(int number)
{
    return this->mPortListPtrs[number];
}

//void GUIComponent::deleteComponent()
//{
//    qDebug() << "GUIComponent:: inside delete component\n";
//    if(this->isSelected())
//    {
//        emit componentDeleted();
//        this->scene()->removeItem(this);
//        delete(this);
//    }
//}

void GUIComponent::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    if(!this->isSelected())
    {
        this->mpSelectionBox->setHovered();
        //this->mpSelectionBox->setVisible(true);
    }
    this->showPorts(true);
}

void GUIComponent::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    if(!this->isSelected())
    {
        this->mpSelectionBox->setPassive();
    }
    this->showPorts(false);
}

void GUIComponent::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    std::cout << "GUIComponent.cpp: " << "contextMenuEvent " << std::endl;

    vector<CompParameter>::iterator it;

    vector<CompParameter> paramVector = this->mpCoreComponent->getParameterVector();

    qDebug() << "This component has the following Parameters: ";
    for ( it=paramVector.begin() ; it !=paramVector.end(); it++ )
        qDebug() << QString::fromStdString(it->getName()) << ": " << it->getValue();

    ParameterDialog *dialog = new ParameterDialog(mpCoreComponent,mpParentGraphicsView);
    dialog->exec();
}

void GUIComponent::keyPressEvent( QKeyEvent *event )
{
    if (event->key() == Qt::Key_Delete)
    {
        //please delete me
        mpParentGraphicsView->deleteComponent(this->getName());
    }
}

QVariant GUIComponent::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if (change == QGraphicsItem::ItemSelectedHasChanged)
    {
        qDebug() << "Component selected status = " << this->isSelected();
        if (this->isSelected())
        {
            this->mpSelectionBox->setActive();
        }
        else
        {
            this->mpSelectionBox->setPassive();
        }
    }
    else if (change == QGraphicsItem::ItemPositionChange)
    {
        emit componentMoved();
    }
    return value;
}

void GUIComponent::showPorts(bool visible)
{
    QList<GUIPort*>::iterator i;
    if(visible)
    {
        for (i = mPortListPtrs.begin(); i != mPortListPtrs.end(); ++i)
        {
            (*i)->show();
        }
    }
    else
        for (i = mPortListPtrs.begin(); i != mPortListPtrs.end(); ++i)
        {
        if ((*i)->mpCorePort->isConnected())
            (*i)->hide();
        }
}

GUIComponentNameTextItem::GUIComponentNameTextItem(GUIComponent *pParent)
    :   QGraphicsTextItem(pParent)
{
    setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
    //setTextInteractionFlags(Qt::TextEditorInteraction);
    mpParentGUIComponent = pParent;
}

void GUIComponentNameTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
    setTextInteractionFlags(Qt::TextEditorInteraction);
}

void GUIComponentNameTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    qDebug() << "GUIComponentTextItem: " << "mouseReleaseEvent";
    emit textMoved(event->pos());
    QGraphicsTextItem::mouseReleaseEvent(event);
}

void GUIComponentNameTextItem::focusOutEvent(QFocusEvent *event)
{
    qDebug() << "GUIComponentTextItem: " << "focusOutEvent";
    //Try to set the new name
    mpParentGUIComponent->setName(toPlainText());
    //refresh the display name (it may be different from the one you wanted)
    mpParentGUIComponent->refreshName();
    emit textMoved(pos());

    setTextInteractionFlags(Qt::NoTextInteraction);

    QGraphicsTextItem::focusOutEvent(event);
}
<commit_msg>emit component deleted signal in destructor<commit_after>//$Id$

#include "HopsanCore.h"
#include "GUIComponent.h"
#include <iostream>
#include "GUIPort.h"
#include "GUIConnector.h"
#include <ostream>
#include <assert.h>
#include <QDebug>

#include <QGraphicsWidget>
#include <QGraphicsSvgItem>
#include <QGraphicsTextItem>
#include <QWidget>
#include <QGraphicsView>
#include <vector>
#include <QGraphicsItem>

#include <QGraphicsSceneMoveEvent>

#include <math.h>
#include "ParameterDialog.h"

GUIComponent::GUIComponent(HopsanEssentials *hopsan, QStringList parameterData, QPoint position, GraphicsScene *scene, QGraphicsItem *parent)
        : QGraphicsWidget(parent)
{
    mpParentGraphicsScene = scene;
    mpParentGraphicsScene->addItem(this);
    mpParentGraphicsView = mpParentGraphicsScene->mpParentProjectTab->mpGraphicsView;

    mTextOffset = 1.1;

    QString componentTypeName = parameterData.at(0);
    QString fileName = parameterData.at(1);
    size_t nPorts = parameterData.at(2).toInt();

    //Core interaction
    mpCoreComponent = hopsan->CreateComponent(componentTypeName.toStdString());
    //

    setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemSendsGeometryChanges | QGraphicsItem::ItemUsesExtendedStyleOption);
    setFocusPolicy(Qt::StrongFocus);
    this->setAcceptHoverEvents(true);

    this->setZValue(10);
    mpIcon = new QGraphicsSvgItem(fileName,this);

    std::cout << "GUIcomponent: " << "x=" << this->pos().x() << "  " << "y=" << this->pos().y() << std::endl;
    std::cout << "GUIcomponent: " << componentTypeName.toStdString() << std::endl;

    setGeometry(0,0,mpIcon->boundingRect().width(),mpIcon->boundingRect().height());

    mpNameText = new GUIComponentNameTextItem(this);
    refreshName(); //Make sure name window is correct size for center positioning
    mpNameText->setPos(QPointF(mpIcon->boundingRect().width()/2-mpNameText->boundingRect().width()/2, mTextOffset*mpIcon->boundingRect().height()));

    //Sets the ports
    for (size_t i = 0; i < nPorts; ++i)
    {
        double x = parameterData.at(3+3*i).toDouble();
        double y = parameterData.at(4+3*i).toDouble();
        double rot = parameterData.at(5+3*i).toDouble();

        QString iconPath("../../HopsanGUI/porticons/");
        if (mpCoreComponent->getPortPtrVector().at(i)->getNodeType() == "NodeSignal")
        {
            iconPath.append("SignalPort");
            if (mpCoreComponent->getPortPtrVector().at(i)->getPortType() == "ReadPort")
                iconPath.append("_read");
            else
                iconPath.append("_write");
        }
        else if (mpCoreComponent->getPortPtrVector().at(i)->getNodeType() == "NodeMechanic")
        {
            iconPath.append("MechanicPort");
            if (mpCoreComponent->getTypeCQS() == "C")
                iconPath.append("C");
            else if (mpCoreComponent->getTypeCQS() == "Q")
                iconPath.append("Q");
        }
        else if (mpCoreComponent->getPortPtrVector().at(i)->getNodeType() == "NodeHydraulic")
        {
            iconPath.append("HydraulicPort");
            if (mpCoreComponent->getTypeCQS() == "C")
                iconPath.append("C");
            else if (mpCoreComponent->getTypeCQS() == "Q")
                iconPath.append("Q");
        }
        else
        {
            assert(false);
        }
        iconPath.append(".svg");

        mPortListPtrs.append(new GUIPort(mpCoreComponent->getPortPtrVector().at(i), x*mpIcon->sceneBoundingRect().width(),y*mpIcon->sceneBoundingRect().height(),rot,iconPath,this));//mpIcon));

    }

    connect(mpNameText, SIGNAL(textMoved(QPointF)), SLOT(fixTextPosition(QPointF)));
    //connect(this->mpParentGraphicsView,SIGNAL(keyPressDelete()),this,SLOT(deleteComponent()));

    setPos(position-QPoint(mpIcon->boundingRect().width()/2, mpIcon->boundingRect().height()/2));

    mpSelectionBox = new GUIComponentSelectionBox(0,0,mpIcon->boundingRect().width(),mpIcon->boundingRect().height(),
                                                  QPen(QColor("red"),3), QPen(QColor("darkRed"),2),this);
    mpSelectionBox->setVisible(false);
}

//GUIComponent::GUIComponent(HopsanEssentials *hopsan, const QString &fileName, QString componentTypeName, QPoint position, QGraphicsView *parentView, QGraphicsItem *parent)
//        : QGraphicsWidget(parent)
//{
//    //Core interaction
//    mpCoreComponent = hopsan->CreateComponent(componentTypeName.toStdString());
//    //
//
//    setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemSendsGeometryChanges | QGraphicsItem::ItemUsesExtendedStyleOption);
//    this->setAcceptHoverEvents(true);
//
//    //widget = new QWidget;
//
//    mpParentView = parentView;
//
//    this->setZValue(10);
//    icon = new QGraphicsSvgItem(fileName,this);
////    icon->setPos(QPointF(-icon->boundingRect().width()/2, -icon->boundingRect().height()/2));
//    std::cout << "GUIcomponent: " << "x=" << this->pos().x() << "  " << "y=" << this->pos().y() << std::endl;
//    std::cout << "GUIcomponent: " << componentTypeName.toStdString() << std::endl;
//
//    //setWindowFlags(Qt::SplashScreen);//just to see the geometry
//    setGeometry(0,0,icon->boundingRect().width(),icon->boundingRect().height());
//
//    mpNameText = new GUIComponentNameTextItem(mpCoreComponent, this);
//    mpNameText->setPos(QPointF(icon->boundingRect().width()/2-mpNameText->boundingRect().width()/2, icon->boundingRect().height()));
//
//    //UGLY UGLY HARD CODED PORT CONNECTION TO CORE...
//    mPortListPtrs.append(new GUIPort(mpCoreComponent->getPortPtrVector().at(0), icon->sceneBoundingRect().width()-5,icon->sceneBoundingRect().height()/2-5,10.0,10.0,this->getParentView(),this,icon));
//    mPortListPtrs.append(new GUIPort(mpCoreComponent->getPortPtrVector().at(1),-5,icon->sceneBoundingRect().height()/2-5,10.0,10.0,this->getParentView(),this,icon));
//
//    this->showPorts(false);
//
//    //icon->setPos(QPointF(-icon->boundingRect().width()/2, -icon->boundingRect().height()/2));
//
//   // rectR->boundingRegion();
//
//    connect(mpNameText, SIGNAL(textMoved(QPointF)), SLOT(fixTextPosition(QPointF)));
//    connect(this->mpParentView,SIGNAL(keyPressDelete()),this,SLOT(deleteComponent()));
//
//    setPos(position-QPoint(icon->boundingRect().width()/2, icon->boundingRect().height()/2));
//
//    mpSelectionBox = new GUIComponentSelectionBox(0,0,icon->boundingRect().width(),icon->boundingRect().height(),
//                                                  QPen(QColor("red"),3), QPen(QColor("darkRed"),2),this);
//    mpSelectionBox->setVisible(false);
//}

double dist(double x1,double y1, double x2, double y2)
{
    return sqrt(pow(x2-x1,2) + pow(y2-y1,2));
}

void GUIComponent::fixTextPosition(QPointF pos)
{
    double x1 = mpIcon->boundingRect().width()/2-mpNameText->boundingRect().width()/2;
    double y1 = mTextOffset*mpIcon->boundingRect().height();

    double x2 = mpIcon->boundingRect().width()/2-mpNameText->boundingRect().width()/2;
    double y2 = -mTextOffset*mpNameText->boundingRect().height();

    double x = mpNameText->mapToParent(pos).x();
    double y = mpNameText->mapToParent(pos).y();

    if (dist(x,y, x1,y1) > dist(x,y, x2,y2))
    {
        mpNameText->setPos(x2,y2);
    }
    else
    {
        mpNameText->setPos(x1,y1);
    }

    std::cout << "GUIComponent::fixTextPosition, x: " << x << " y: " << y << std::endl;

}

void GUIComponent::mouseReleaseEvent ( QGraphicsSceneMouseEvent * event )
{
    qDebug() << "GUIComponent: " << "mouseReleaseEvent";
    QGraphicsItem::mouseReleaseEvent(event);
}

GUIComponent::~GUIComponent()
{
    //delete widget;
    emit componentDeleted();
}

//QGraphicsView *GUIComponent::getParentView()
//{
//    return mpParentView;
//}

void GUIComponent::addConnector(GUIConnector *item)
{
    connect(this,SIGNAL(componentMoved()),item,SLOT(updatePos()));
}

//! This function refreshes the displayed name (HopsanCore may have changed it)
void GUIComponent::refreshName()
{
    mpNameText->setPlainText(getName());
    //Adjust the position of the text
}

//! This function returns the current component name
QString GUIComponent::getName()
{
    return QString::fromStdString(mpCoreComponent->getName());
}

//! This function sets the desired component name
void GUIComponent::setName(QString name)
{
    mpCoreComponent->setName(name.toStdString());
    refreshName();
}

GUIPort *GUIComponent::getPort(int number)
{
    return this->mPortListPtrs[number];
}

//void GUIComponent::deleteComponent()
//{
//    qDebug() << "GUIComponent:: inside delete component\n";
//    if(this->isSelected())
//    {
//        emit componentDeleted();
//        this->scene()->removeItem(this);
//        delete(this);
//    }
//}

void GUIComponent::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    if(!this->isSelected())
    {
        this->mpSelectionBox->setHovered();
        //this->mpSelectionBox->setVisible(true);
    }
    this->showPorts(true);
}

void GUIComponent::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    if(!this->isSelected())
    {
        this->mpSelectionBox->setPassive();
    }
    this->showPorts(false);
}

void GUIComponent::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    std::cout << "GUIComponent.cpp: " << "contextMenuEvent " << std::endl;

    vector<CompParameter>::iterator it;

    vector<CompParameter> paramVector = this->mpCoreComponent->getParameterVector();

    qDebug() << "This component has the following Parameters: ";
    for ( it=paramVector.begin() ; it !=paramVector.end(); it++ )
        qDebug() << QString::fromStdString(it->getName()) << ": " << it->getValue();

    ParameterDialog *dialog = new ParameterDialog(mpCoreComponent,mpParentGraphicsView);
    dialog->exec();
}

void GUIComponent::keyPressEvent( QKeyEvent *event )
{
    if (event->key() == Qt::Key_Delete)
    {
        //please delete me
        mpParentGraphicsView->deleteComponent(this->getName());
    }
}

QVariant GUIComponent::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if (change == QGraphicsItem::ItemSelectedHasChanged)
    {
        qDebug() << "Component selected status = " << this->isSelected();
        if (this->isSelected())
        {
            this->mpSelectionBox->setActive();
        }
        else
        {
            this->mpSelectionBox->setPassive();
        }
    }
    else if (change == QGraphicsItem::ItemPositionChange)
    {
        emit componentMoved();
    }
    return value;
}

void GUIComponent::showPorts(bool visible)
{
    QList<GUIPort*>::iterator i;
    if(visible)
    {
        for (i = mPortListPtrs.begin(); i != mPortListPtrs.end(); ++i)
        {
            (*i)->show();
        }
    }
    else
        for (i = mPortListPtrs.begin(); i != mPortListPtrs.end(); ++i)
        {
        if ((*i)->mpCorePort->isConnected())
            (*i)->hide();
        }
}

GUIComponentNameTextItem::GUIComponentNameTextItem(GUIComponent *pParent)
    :   QGraphicsTextItem(pParent)
{
    setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
    //setTextInteractionFlags(Qt::TextEditorInteraction);
    mpParentGUIComponent = pParent;
}

void GUIComponentNameTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
    setTextInteractionFlags(Qt::TextEditorInteraction);
}

void GUIComponentNameTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    qDebug() << "GUIComponentTextItem: " << "mouseReleaseEvent";
    emit textMoved(event->pos());
    QGraphicsTextItem::mouseReleaseEvent(event);
}

void GUIComponentNameTextItem::focusOutEvent(QFocusEvent *event)
{
    qDebug() << "GUIComponentTextItem: " << "focusOutEvent";
    //Try to set the new name
    mpParentGUIComponent->setName(toPlainText());
    //refresh the display name (it may be different from the one you wanted)
    mpParentGUIComponent->refreshName();
    emit textMoved(pos());

    setTextInteractionFlags(Qt::NoTextInteraction);

    QGraphicsTextItem::focusOutEvent(event);
}
<|endoftext|>


<commit_before>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>
using namespace std;
template<typename T>
auto newcopy( const T * item, size_t size, size_t count) -> T* //strong
{
	T * buff = new T[size];
	try {
		copy(item, item + count, buff);
	}
	catch(...){
		delete[] buff;
	}
		return buff;
}
template <typename T>
class stack
{
public:
	stack(); //noexcept
	stack(stack const &);  //strong
	~stack(); //noexcept
	size_t count() const;  //noexcept
	auto push(T const &) -> void; //strong
	T pop(); //strong
	//T top() const; //strong
	auto operator=(stack const & right)->stack &; //strong
	auto empty() const -> bool; //noexcept

private:
	T * array_;
	size_t array_size_;
	size_t count_;
};
template <typename T>
size_t stack<T>::count() const
{
	return count_;
}
template <typename T>
stack<T>::stack():array_ (nullptr), array_size_(0), count_(0)
{

}

template<typename T>
stack<T>::stack(stack const & item):array_size_(item.array_size_), count_(item.count_),array_(newcopy(item.array_, item.array_size_,item.count_))
{

}

template <typename T>
stack<T>::~stack()
{
	delete[] array_;
}

template<typename T>
auto stack<T>::push(T const & item) -> void {
	if (count_ == array_size_) {
		size_t size = array_size_ * 2 + (array_size_ == 0) ;
		T * buff = newcopy(array_, size, array_size_);
		delete[] array_;
		array_ = buff;
		array_size_ = size;
	}
	array_[count_] = item;
	++count_;
}

/*template<typename T>
void stack<T>::pop() {
	if (count_ == 0) {
		throw std::logic_error("Stack is empty!");
	} else {
		count_--;
	}
}*/
template<typename T>
T stack<T>::pop() {
	if (count_ == 0) {
		throw std::logic_error("Stack is empty!");
	}
	return array_[--count_];
}

template<typename T>
/*T stack<T>::top() const
{
	if (count_ == 0) {
		throw ("Stack is empty!");
	}
	return array_[count_ - 1];
}*/

template<typename T>
auto stack<T>::operator=(stack const & right) -> stack & {
	if (this != &right) {
	T* buff = newcopy(right.array_, right.array_size_, right.count_);
	delete[] array_;
	array_ = buff;
	count_ = right.count_;
	array_size_ = right.array_size_;
	}
	return *this;
}

template<typename T>
auto stack<T>::empty() const -> bool{
	if (count_ == 0){
		return true;
	} else{
		return false;
	}
}

#endif
<commit_msg>Update stack.cpp<commit_after>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>
using namespace std;
template<typename T>
auto newcopy( const T * item, size_t size, size_t count) -> T* //strong
{
	T * buff = new T[size];
	try {
		copy(item, item + count, buff);
	}
	catch(...){
		delete[] buff;
		throw;
	}
		return buff;
}
template <typename T>
class stack
{
public:
	stack(); //noexcept
	stack(stack const &);  //strong
	~stack(); //noexcept
	size_t count() const;  //noexcept
	auto push(T const &) -> void; //strong
	T pop(); //strong
	//T top() const; //strong
	auto operator=(stack const & right)->stack &; //strong
	auto empty() const -> bool; //noexcept

private:
	T * array_;
	size_t array_size_;
	size_t count_;
};
template <typename T>
size_t stack<T>::count() const
{
	return count_;
}
template <typename T>
stack<T>::stack():array_ (nullptr), array_size_(0), count_(0)
{

}

template<typename T>
stack<T>::stack(stack const & item):array_size_(item.array_size_), count_(item.count_),array_(newcopy(item.array_, item.array_size_,item.count_))
{

}

template <typename T>
stack<T>::~stack()
{
	delete[] array_;
}

template<typename T>
auto stack<T>::push(T const & item) -> void {
	if (count_ == array_size_) {
		size_t size = array_size_ * 2 + (array_size_ == 0) ;
		T * buff = newcopy(array_, size, array_size_);
		delete[] array_;
		array_ = buff;
		array_size_ = size;
	}
	array_[count_] = item;
	++count_;
}

/*template<typename T>
void stack<T>::pop() {
	if (count_ == 0) {
		throw std::logic_error("Stack is empty!");
	} else {
		count_--;
	}
}*/
template<typename T>
T stack<T>::pop() {
	if (count_ == 0) {
		throw std::logic_error("Stack is empty!");
	}
	return array_[--count_];
}

template<typename T>
/*T stack<T>::top() const
{
	if (count_ == 0) {
		throw ("Stack is empty!");
	}
	return array_[count_ - 1];
}*/

template<typename T>
auto stack<T>::operator=(stack const & right) -> stack & {
	if (this != &right) {
	T* buff = newcopy(right.array_, right.array_size_, right.count_);
	delete[] array_;
	array_ = buff;
	count_ = right.count_;
	array_size_ = right.array_size_;
	}
	return *this;
}

template<typename T>
auto stack<T>::empty() const -> bool{
	if (count_ == 0){
		return true;
	} else{
		return false;
	}
}

#endif
<|endoftext|>


<commit_before>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>

template <typename T>
class stack
{
public:
	stack();									//noexcept
	stack(stack const &);								//strong
	~stack();									//noexcept
	size_t count() const;								//noexcept
	auto push(T const &) -> void;							//strong
	void pop();									//basic
	const T& top();									//strong
	auto operator=(stack const & right)->stack &;					//strong
private:
	T *array_;
	size_t array_size_;
	size_t count_;
};
template<typename T>
auto newcopy(const T * item, size_t size, size_t count) -> T* 				//strong
{
	T * buff = new T[size];
	try
	{
		std::copy(item, item + count, buff);
	}
	catch (...)
	{
		delete[] buff;
		throw;
	}
	return buff;
}
template <typename T>
size_t stack<T>::count() const
{
	return count_;
}
template <typename T>
stack<T>::stack()
{
	array_size_ = 0;
	array_ = new T[array_size_];
	count_ = 0;
}

template<typename T>
stack<T>::stack(stack const & other) :array_size_(other.array_size_), count_(other.count_), array_(newcopy(other.array_, other.array_size_, other.count_))
{

}

template <typename T>
stack<T>::~stack()
{
	delete[] array_;
}

template<typename T>
void stack<T>::push(T const &item)
{
	if (count_ == array_size_)
	{
		size_t size = array_size_ * 2 + (array_size_ == 0);
		delete[] array_;
		array_ = newcopy(array_, size, array_size_);
		array_size_ = size;
	}
	array_[count_] = item;
	++count_;
}
template<typename T>
void stack<T>::pop()
{
	if (count_ == 0)
	{
		throw std::logic_error("Stack is empty!");
	}
	else
	{
		count_--;
	}
}

template<typename T>
const T& stack<T>::top()
{
	if (count_ == 0)
	{
		throw ("Stack is empty!");
	}
	return array_[count_ - 1];
}

template<typename T>
auto stack<T>::operator=(stack const & right) -> stack &
{
	if (this != &right)
	{
		delete[] array_;
		newcopy(right.array_, right.array_size_, right.count_);
	}
	return *this;
}
#endif
<commit_msg>Update stack.cpp<commit_after>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>

template <typename T>
class stack
{
public:
	stack();									//noexcept
	stack(stack const &);								//strong
	~stack();									//noexcept
	size_t count() const;								//noexcept
	auto push(T const &) -> void;							//strong
	void pop();									//basic
	const T& top();									//strong
	auto operator=(stack const & right)->stack &;					//strong
	auto empty() const -> bool; 							//noexcept
private:
	T *array_;
	size_t array_size_;
	size_t count_;
};
template<typename T>
auto newcopy(const T * item, size_t size, size_t count) -> T* 				//strong
{
	T * buff = new T[size];
	try
	{
		std::copy(item, item + count, buff);
	}
	catch (...)
	{
		delete[] buff;
		throw;
	}
	return buff;
}
template <typename T>
size_t stack<T>::count() const
{
	return count_;
}
template <typename T>
stack<T>::stack()
{
	array_size_ = 0;
	array_ = new T[array_size_];
	count_ = 0;
}

template<typename T>
stack<T>::stack(stack const & other) :array_size_(other.array_size_), count_(other.count_), array_(newcopy(other.array_, other.array_size_, other.count_))
{

}

template <typename T>
stack<T>::~stack()
{
	delete[] array_;
}

template<typename T>
void stack<T>::push(T const &item)
{
	if (count_ == array_size_)
	{
		size_t size = array_size_ * 2 + (array_size_ == 0);
		delete[] array_;
		array_ = newcopy(array_, size, array_size_);
		array_size_ = size;
	}
	array_[count_] = item;
	++count_;
}
template<typename T>
void stack<T>::pop()
{
	if (count_ == 0)
	{
		throw std::logic_error("Stack is empty!");
	}
	else
	{
		count_--;
	}
}

template<typename T>
const T& stack<T>::top()
{
	if (count_ == 0)
	{
		throw ("Stack is empty!");
	}
	return array_[count_ - 1];
}

template<typename T>
auto stack<T>::operator=(stack const & right) -> stack &
{
	if (this != &right)
	{
		delete[] array_;
		newcopy(right.array_, right.array_size_, right.count_);
	}
	return *this;
}

template<typename T>
auto stack<T>::empty() const -> bool
{
	if (count_ == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}
#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <mutex>
#include <thread>
#include <memory>

using namespace std;

template <typename T>
class stack
{
public:
	stack();/*noexept*/
	stack(const stack<T> &);/*strong*/
	size_t count() const; /*noexcept*/
	void print()const;/*noexcept*/
	void push(T const &); /*strong*/
	void swap(stack<T>&); /*noexcept*/
	auto pop()->std::shared_ptr<T>; /*strong*/
	T top(); /*strong*/
	bool empty() const; /*noexcept*/
	stack<T>& operator=(stack<T> &); /*noexcept*/
	~stack();/*noexcept*/
private:
	T * array_;
	mutable std::mutex mutex_;
	size_t array_size_;
	size_t count_;
};

template <typename T>
stack<T>::stack() : count_(0), array_size_(0), array_{ nullptr }
{}

template<class T>
stack<T>::~stack()
{
	count_ = 0;
	array_size_ = 0;
	delete[] array_;
}

template <typename T>
stack<T>::stack(const stack<T>& copy)
{
	std::lock_guard<std::mutex> lock(mutex_);
	T *tmp = new T[copy.array_size_];
	count_ = copy.count_;
	array_size_ = copy.array_size_;
	array_ = tmp;
	if(array_ == nullptr){
		throw "error";
		delete[] array_;
	}
	std::copy(copy.array_, copy.array_ + count_, array_);
}

template<class T>
size_t stack<T>::count() const
{
	std::lock_guard<std::mutex> lock(mutex_);
	return count_;
}

template <typename T>
bool stack<T>::empty() const
{
	return (count_ == 0);
}

template<typename T>
void stack<T>::swap(stack& x)
{
	other.mutex_.lock();
	std::swap(x.array_size_, array_size_);
	std::swap(count_, x.count_);
	std::swap(x.array_, array_);
	other.mutex_.unlock();
}

template <typename T>
T stack<T>::top()
{
	if (empty())
	{
		throw "Stack is empty!";
	}
	return array_[count_ - 1];
}

template <typename T>
void stack<T>::push(T const &value)
{
	mutex_.lock();
	if (array_size_ == count_)
	{
		array_size_ *= 2;
		stack<T> temp(*this);
		swap(temp);
	}
	array_[count_] = value;
	++count_;
	mutex_.unlock();
}

template <typename T>
auto stack<T>::pop() -> std::shared_ptr<T>
{
	std::lock_guard<std::mutex> lock(mutex_);
	if (empty())
		throw "Stack is empty" ;
	count_--;
}

template <typename T>
void stack<T>::print() const
{
	for (int i = 0; i < array_size_; i++)
		cout << array_[i];
}

template<typename T>
stack<T>& stack<T>::operator=(stack<T> & other)
{
	std::lock_guard<std::mutex> lock(obj.mutex_);
	if (this != &other)
	{
		stack<T> tmp(other);
		tmp.swap(*this);
	}
	return *this;
}
<commit_msg>Update stack.hpp<commit_after>#include <iostream>
#include <mutex>
#include <thread>
#include <memory>

using namespace std;

template <typename T>
class stack
{
public:
	stack();/*noexept*/
	stack(const stack<T> &);/*strong*/
	size_t count() const; /*noexcept*/
	void print()const;/*noexcept*/
	void push(T const &); /*strong*/
	void swap(stack<T>&); /*noexcept*/
	auto pop()->std::shared_ptr<T>; /*strong*/
	T top(); /*strong*/
	bool empty() const; /*noexcept*/
	stack<T>& operator=(stack<T> &); /*noexcept*/
	~stack();/*noexcept*/
private:
	T * array_;
	mutable std::mutex mutex_;
	size_t array_size_;
	size_t count_;
};

template <typename T>
stack<T>::stack() : count_(0), array_size_(0), array_{ nullptr }
{}

template<class T>
stack<T>::~stack()
{
	count_ = 0;
	array_size_ = 0;
	delete[] array_;
}

template <typename T>
stack<T>::stack(const stack<T>& copy)
{
	std::lock_guard<std::mutex> lock(mutex_);
	T *tmp = new T[copy.array_size_];
	count_ = copy.count_;
	array_size_ = copy.array_size_;
	array_ = tmp;
	if(array_ == nullptr){
		throw "error";
		delete[] array_;
	}
	std::copy(copy.array_, copy.array_ + count_, array_);
}

template<class T>
size_t stack<T>::count() const
{
	std::lock_guard<std::mutex> lock(mutex_);
	return count_;
}

template <typename T>
bool stack<T>::empty() const
{
	return (count_ == 0);
}

template<typename T>
void stack<T>::swap(stack& x)
{
	other.mutex_.lock();
	std::swap(x.array_size_, array_size_);
	std::swap(count_, x.count_);
	std::swap(x.array_, array_);
	other.mutex_.unlock();
}

template <typename T>
T stack<T>::top()
{
	if (empty())
	{
		throw "Stack is empty!";
	}
	return array_[count_ - 1];
}

template <typename T>
void stack<T>::push(T const &value)
{
	mutex_.lock();
	if (array_size_ == count_)
	{
		array_size_ *= 2;
		stack<T> temp(*this);
		swap(temp);
	}
	array_[count_] = value;
	++count_;
	mutex_.unlock();
}

template <typename T>
auto stack<T>::pop() -> std::shared_ptr<T>
{
	std::lock_guard<std::mutex> lock(mutex_);
	if (empty())
		throw "Stack is empty" ;
	count_--;
}

template <typename T>
void stack<T>::print() const
{
	for (int i = 0; i < array_size_; i++)
		cout << array_[i];
}

template<typename T>
stack<T>& stack<T>::operator=(stack<T> & other)
{
	std::lock_guard<std::mutex> lock(other.mutex_);
	if (this != &other)
	{
		stack<T> tmp(other);
		tmp.swap(*this);
	}
	return *this;
}
<|endoftext|>


<commit_before>#ifndef STACK_HPP
#define STACK_HPP
#include <cstdlib>
#include <iostream>
#include <memory>

template <typename T>
class allocator {
protected:
	allocator(size_t size = 0);
	~allocator();
	auto swap(allocator & other) -> void;

	allocator(allocator const &) = delete;
	auto operator=(allocator const &)->allocator & = delete;

	T * ptr_;
	size_t size_;
	size_t count_;
};

template <typename T>
class stack : private allocator<T>
{
public:
	stack();
	size_t count() const;
	void push(T const &elem);
	size_t pop();
	const T& top();
	~stack();
	stack(const stack &b);
	stack & operator=(const stack &b);
	bool operator==(stack const & _s);
	bool empty() const noexcept;
	void swap(stack &v);
};
template<typename T>
T*copy_new(const T*arr,size_t count,size_t array_size)
{

	T*l= new T[array_size];
	try
	{
		std::copy(arr,arr+count,l);
	}
	catch(...)
	{
		delete[] l;
		throw;
	}
	return l;

}
#include "stack.cpp"
#endif
<commit_msg>Update stack.hpp<commit_after>#ifndef STACK_HPP
#define STACK_HPP
#include <cstdlib>
#include <iostream>
#include <memory>

template <typename T>
class allocator {
protected:
	allocator(size_t size = 0);
	~allocator();
	auto swap(allocator & other) -> void;

	allocator(allocator const &) = delete;
	auto operator=(allocator const &)->allocator & = delete;

	T * ptr_;
	size_t size_;
	size_t count_;
};

template <typename T>
class stack : private allocator<T>
{
public:
	stack(size_t size = 0);
	size_t count() const;
	void push(T const &elem);
	size_t pop();
	const T& top();
	~stack();
	stack(const stack &b);
	stack & operator=(const stack &b);
	bool operator==(stack const & _s);
	bool empty() const noexcept;
};

#include "stack.cpp"
#endif
<|endoftext|>


<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/yosys.h"
#include "kernel/sigtools.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct ChformalPass : public Pass {
	ChformalPass() : Pass("chformal", "change formal constraints of the design") { }
	virtual void help()
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    chformal [types] [mode] [options] [selection]\n");
		log("\n");
		log("Make changes to the formal constraints of the design. The [types] options\n");
		log("the type of constraint to operate on. If none of the folling options is given,\n");
		log("the command will operate on all constraint types:\n");
		log("\n");
		log("    -assert       $assert cells, representing assert(...) constraints\n");
		log("    -assume       $assume cells, representing assume(...) constraints\n");
		log("    -live         $live cells, representing assert(s_eventually ...)\n");
		log("    -fair         $fair cells, representing assume(s_eventually ...)\n");
		log("    -cover        $cover cells, representing cover() statements\n");
		log("\n");
		log("Exactly one of the following modes must be specified:\n");
		log("\n");
		log("    -remove\n");
		log("        remove the cells and thus constraints from the design\n");
		log("\n");
		log("    -early\n");
		log("        bypass FFs that only delay the activation of a constraint\n");
		log("\n");
		log("    -delay <N>\n");
		log("        delay activation of the constraint by <N> clock cycles\n");
		log("\n");
		log("    -skip <N>\n");
		log("        ignore activation of the constraint in the first <N> clock cycles\n");
		log("\n");
		log("    -assert2assume\n");
		log("    -assume2assert\n");
		log("    -live2fair\n");
		log("    -fair2live\n");
		log("        change the roles of cells as indicated. this options can be combined\n");
		log("\n");
	}
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
	{
		bool assert2assume = false;
		bool assume2assert = false;
		bool live2fair = false;
		bool fair2live = false;

		pool<IdString> constr_types;
		char mode = 0;
		int mode_arg;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			if (args[argidx] == "-assert") {
				constr_types.insert("$assert");
				continue;
			}
			if (args[argidx] == "-assume") {
				constr_types.insert("$assume");
				continue;
			}
			if (args[argidx] == "-live") {
				constr_types.insert("$live");
				continue;
			}
			if (args[argidx] == "-fair") {
				constr_types.insert("$fair");
				continue;
			}
			if (args[argidx] == "-cover") {
				constr_types.insert("$cover");
				continue;
			}
			if (mode == 0 && args[argidx] == "-remove") {
				mode = 'r';
				continue;
			}
			if (mode == 0 && args[argidx] == "-early") {
				mode = 'e';
				continue;
			}
			if (mode == 0 && args[argidx] == "-delay" && argidx+1 < args.size()) {
				mode = 'd';
				mode_arg = atoi(args[++argidx].c_str());
				continue;
			}
			if (mode == 0 && args[argidx] == "-skip" && argidx+1 < args.size()) {
				mode = 's';
				mode_arg = atoi(args[++argidx].c_str());
				continue;
			}
			if ((mode == 0 || mode == 'c') && args[argidx] == "-assert2assume") {
				assert2assume = true;
				mode = 'c';
				continue;
			}
			if ((mode == 0 || mode == 'c') && args[argidx] == "-assume2assert") {
				assume2assert = true;
				mode = 'c';
				continue;
			}
			if ((mode == 0 || mode == 'c') && args[argidx] == "-live2fair") {
				live2fair = true;
				mode = 'c';
				continue;
			}
			if ((mode == 0 || mode == 'c') && args[argidx] == "-fair2live") {
				fair2live = true;
				mode = 'c';
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		if (constr_types.empty()) {
			constr_types.insert("$assert");
			constr_types.insert("$assume");
			constr_types.insert("$live");
			constr_types.insert("$fair");
			constr_types.insert("$cover");
		}

		if (mode == 0)
			log_cmd_error("Mode option is missing.\n");

		for (auto module : design->selected_modules())
		{
			vector<Cell*> constr_cells;

			for (auto cell : module->selected_cells())
				if (constr_types.count(cell->type))
					constr_cells.push_back(cell);

			if (mode == 'r')
			{
				for (auto cell : constr_cells)
					module->remove(cell);
			}
			else
			if (mode == 'e')
			{
				SigMap sigmap(module);
				dict<SigBit, pair<SigBit, pair<SigBit, bool>>> ffmap;
				pool<SigBit> init_zero, init_one;

				for (auto wire : module->wires())
				{
					if (wire->attributes.count("\\init") == 0)
						continue;

					SigSpec initsig = sigmap(wire);
					Const initval = wire->attributes.at("\\init");

					for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++) {
						if (initval[i] == State::S0)
							init_zero.insert(initsig[i]);
						if (initval[i] == State::S1)
							init_one.insert(initsig[i]);
					}
				}

				for (auto cell : module->selected_cells())
				{
					if (cell->type == "$ff") {
						SigSpec D = sigmap(cell->getPort("\\D"));
						SigSpec Q = sigmap(cell->getPort("\\Q"));
						for (int i = 0; i < GetSize(D); i++)
							ffmap[Q[i]] = make_pair(D[i], make_pair(State::Sm, false));
					}
					if (cell->type == "$dff") {
						SigSpec D = sigmap(cell->getPort("\\D"));
						SigSpec Q = sigmap(cell->getPort("\\Q"));
						SigSpec C = sigmap(cell->getPort("\\CLK"));
						bool clockpol = cell->getParam("\\CLK_POLARITY").as_bool();
						for (int i = 0; i < GetSize(D); i++)
							ffmap[Q[i]] = make_pair(D[i], make_pair(C, clockpol));
					}
				}

				for (auto cell : constr_cells)
					while (true)
					{
						SigSpec A = sigmap(cell->getPort("\\A"));
						SigSpec EN = sigmap(cell->getPort("\\EN"));

						if (ffmap.count(A) == 0 || ffmap.count(EN) == 0)
							break;

						if (!init_zero.count(EN)) {
							if (cell->type == "$cover") break;
							if (cell->type.in("$assert", "$assume") && !init_one.count(A)) break;
						}

						const auto &A_map = ffmap.at(A);
						const auto &EN_map = ffmap.at(EN);

						if (A_map.second != EN_map.second)
							break;

						cell->setPort("\\A", A_map.first);
						cell->setPort("\\EN", EN_map.first);
					}
			}
			else
			if (mode == 'd')
			{
				for (auto cell : constr_cells)
				for (int i = 0; i < mode_arg; i++)
				{
					SigSpec orig_a = cell->getPort("\\A");
					SigSpec orig_en = cell->getPort("\\EN");

					Wire *new_a = module->addWire(NEW_ID);
					Wire *new_en = module->addWire(NEW_ID);
					new_en->attributes["\\init"] = State::S0;

					module->addFf(NEW_ID, orig_a, new_a);
					module->addFf(NEW_ID, orig_en, new_en);

					cell->setPort("\\A", new_a);
					cell->setPort("\\EN", new_en);
				}
			}
			else
			if (mode == 's')
			{
				SigSpec en = State::S1;

				for (int i = 0; i < mode_arg; i++) {
					Wire *w = module->addWire(NEW_ID);
					w->attributes["\\init"] = State::S0;
					module->addFf(NEW_ID, en, w);
					en = w;
				}

				for (auto cell : constr_cells)
					cell->setPort("\\EN", module->LogicAnd(NEW_ID, en, cell->getPort("\\EN")));
			}
			else
			if (mode == 'c')
			{
				for (auto cell : constr_cells)
					if (assert2assume && cell->type == "$assert")
						cell->type = "$assume";
					else if (assume2assert && cell->type == "$assume")
						cell->type = "$assert";
					else if (live2fair && cell->type == "$live")
						cell->type = "$fair";
					else if (fair2live && cell->type == "$fair")
						cell->type = "$live";
			}
		}
	}
} ChformalPass;

PRIVATE_NAMESPACE_END
<commit_msg>Fix gcc compiler warning<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/yosys.h"
#include "kernel/sigtools.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct ChformalPass : public Pass {
	ChformalPass() : Pass("chformal", "change formal constraints of the design") { }
	virtual void help()
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    chformal [types] [mode] [options] [selection]\n");
		log("\n");
		log("Make changes to the formal constraints of the design. The [types] options\n");
		log("the type of constraint to operate on. If none of the folling options is given,\n");
		log("the command will operate on all constraint types:\n");
		log("\n");
		log("    -assert       $assert cells, representing assert(...) constraints\n");
		log("    -assume       $assume cells, representing assume(...) constraints\n");
		log("    -live         $live cells, representing assert(s_eventually ...)\n");
		log("    -fair         $fair cells, representing assume(s_eventually ...)\n");
		log("    -cover        $cover cells, representing cover() statements\n");
		log("\n");
		log("Exactly one of the following modes must be specified:\n");
		log("\n");
		log("    -remove\n");
		log("        remove the cells and thus constraints from the design\n");
		log("\n");
		log("    -early\n");
		log("        bypass FFs that only delay the activation of a constraint\n");
		log("\n");
		log("    -delay <N>\n");
		log("        delay activation of the constraint by <N> clock cycles\n");
		log("\n");
		log("    -skip <N>\n");
		log("        ignore activation of the constraint in the first <N> clock cycles\n");
		log("\n");
		log("    -assert2assume\n");
		log("    -assume2assert\n");
		log("    -live2fair\n");
		log("    -fair2live\n");
		log("        change the roles of cells as indicated. this options can be combined\n");
		log("\n");
	}
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
	{
		bool assert2assume = false;
		bool assume2assert = false;
		bool live2fair = false;
		bool fair2live = false;

		pool<IdString> constr_types;
		char mode = 0;
		int mode_arg = 0;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			if (args[argidx] == "-assert") {
				constr_types.insert("$assert");
				continue;
			}
			if (args[argidx] == "-assume") {
				constr_types.insert("$assume");
				continue;
			}
			if (args[argidx] == "-live") {
				constr_types.insert("$live");
				continue;
			}
			if (args[argidx] == "-fair") {
				constr_types.insert("$fair");
				continue;
			}
			if (args[argidx] == "-cover") {
				constr_types.insert("$cover");
				continue;
			}
			if (mode == 0 && args[argidx] == "-remove") {
				mode = 'r';
				continue;
			}
			if (mode == 0 && args[argidx] == "-early") {
				mode = 'e';
				continue;
			}
			if (mode == 0 && args[argidx] == "-delay" && argidx+1 < args.size()) {
				mode = 'd';
				mode_arg = atoi(args[++argidx].c_str());
				continue;
			}
			if (mode == 0 && args[argidx] == "-skip" && argidx+1 < args.size()) {
				mode = 's';
				mode_arg = atoi(args[++argidx].c_str());
				continue;
			}
			if ((mode == 0 || mode == 'c') && args[argidx] == "-assert2assume") {
				assert2assume = true;
				mode = 'c';
				continue;
			}
			if ((mode == 0 || mode == 'c') && args[argidx] == "-assume2assert") {
				assume2assert = true;
				mode = 'c';
				continue;
			}
			if ((mode == 0 || mode == 'c') && args[argidx] == "-live2fair") {
				live2fair = true;
				mode = 'c';
				continue;
			}
			if ((mode == 0 || mode == 'c') && args[argidx] == "-fair2live") {
				fair2live = true;
				mode = 'c';
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		if (constr_types.empty()) {
			constr_types.insert("$assert");
			constr_types.insert("$assume");
			constr_types.insert("$live");
			constr_types.insert("$fair");
			constr_types.insert("$cover");
		}

		if (mode == 0)
			log_cmd_error("Mode option is missing.\n");

		for (auto module : design->selected_modules())
		{
			vector<Cell*> constr_cells;

			for (auto cell : module->selected_cells())
				if (constr_types.count(cell->type))
					constr_cells.push_back(cell);

			if (mode == 'r')
			{
				for (auto cell : constr_cells)
					module->remove(cell);
			}
			else
			if (mode == 'e')
			{
				SigMap sigmap(module);
				dict<SigBit, pair<SigBit, pair<SigBit, bool>>> ffmap;
				pool<SigBit> init_zero, init_one;

				for (auto wire : module->wires())
				{
					if (wire->attributes.count("\\init") == 0)
						continue;

					SigSpec initsig = sigmap(wire);
					Const initval = wire->attributes.at("\\init");

					for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++) {
						if (initval[i] == State::S0)
							init_zero.insert(initsig[i]);
						if (initval[i] == State::S1)
							init_one.insert(initsig[i]);
					}
				}

				for (auto cell : module->selected_cells())
				{
					if (cell->type == "$ff") {
						SigSpec D = sigmap(cell->getPort("\\D"));
						SigSpec Q = sigmap(cell->getPort("\\Q"));
						for (int i = 0; i < GetSize(D); i++)
							ffmap[Q[i]] = make_pair(D[i], make_pair(State::Sm, false));
					}
					if (cell->type == "$dff") {
						SigSpec D = sigmap(cell->getPort("\\D"));
						SigSpec Q = sigmap(cell->getPort("\\Q"));
						SigSpec C = sigmap(cell->getPort("\\CLK"));
						bool clockpol = cell->getParam("\\CLK_POLARITY").as_bool();
						for (int i = 0; i < GetSize(D); i++)
							ffmap[Q[i]] = make_pair(D[i], make_pair(C, clockpol));
					}
				}

				for (auto cell : constr_cells)
					while (true)
					{
						SigSpec A = sigmap(cell->getPort("\\A"));
						SigSpec EN = sigmap(cell->getPort("\\EN"));

						if (ffmap.count(A) == 0 || ffmap.count(EN) == 0)
							break;

						if (!init_zero.count(EN)) {
							if (cell->type == "$cover") break;
							if (cell->type.in("$assert", "$assume") && !init_one.count(A)) break;
						}

						const auto &A_map = ffmap.at(A);
						const auto &EN_map = ffmap.at(EN);

						if (A_map.second != EN_map.second)
							break;

						cell->setPort("\\A", A_map.first);
						cell->setPort("\\EN", EN_map.first);
					}
			}
			else
			if (mode == 'd')
			{
				for (auto cell : constr_cells)
				for (int i = 0; i < mode_arg; i++)
				{
					SigSpec orig_a = cell->getPort("\\A");
					SigSpec orig_en = cell->getPort("\\EN");

					Wire *new_a = module->addWire(NEW_ID);
					Wire *new_en = module->addWire(NEW_ID);
					new_en->attributes["\\init"] = State::S0;

					module->addFf(NEW_ID, orig_a, new_a);
					module->addFf(NEW_ID, orig_en, new_en);

					cell->setPort("\\A", new_a);
					cell->setPort("\\EN", new_en);
				}
			}
			else
			if (mode == 's')
			{
				SigSpec en = State::S1;

				for (int i = 0; i < mode_arg; i++) {
					Wire *w = module->addWire(NEW_ID);
					w->attributes["\\init"] = State::S0;
					module->addFf(NEW_ID, en, w);
					en = w;
				}

				for (auto cell : constr_cells)
					cell->setPort("\\EN", module->LogicAnd(NEW_ID, en, cell->getPort("\\EN")));
			}
			else
			if (mode == 'c')
			{
				for (auto cell : constr_cells)
					if (assert2assume && cell->type == "$assert")
						cell->type = "$assume";
					else if (assume2assert && cell->type == "$assume")
						cell->type = "$assert";
					else if (live2fair && cell->type == "$live")
						cell->type = "$fair";
					else if (fair2live && cell->type == "$fair")
						cell->type = "$live";
			}
		}
	}
} ChformalPass;

PRIVATE_NAMESPACE_END
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------//
/*
  Copyright (c) 2014, Stuart R. Slattery
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:

  *: Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.

  *: Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.

  *: Neither the name of the Oak Ridge National Laboratory nor the
  names of its contributors may be used to endorse or promote products
  derived from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//---------------------------------------------------------------------------//
/*!
 * \brief DTK_STKMeshEntityLocalMap.cpp
 * \author Stuart R. Slattery
 * \brief Forward and reverse local mappings for entities.
 */
//---------------------------------------------------------------------------//

#include "DTK_STKMeshEntityLocalMap.hpp"
#include "DTK_STKMeshHelpers.hpp"
#include "DTK_IntrepidCellLocalMap.hpp"
#include "DTK_ProjectionPrimitives.hpp"
#include "DTK_DBC.hpp"

#include <Intrepid_FieldContainer.hpp>

#include <stk_mesh/base/MetaData.hpp>
#include <stk_mesh/base/Part.hpp>
#include <stk_mesh/base/Selector.hpp>
#include <stk_topology/topology.hpp>

namespace DataTransferKit
{
//---------------------------------------------------------------------------//
// Constructor.
STKMeshEntityLocalMap::STKMeshEntityLocalMap(
    const Teuchos::RCP<stk::mesh::BulkData>& bulk_data )
    : d_bulk_data( bulk_data )
{ /* ... */ }

//---------------------------------------------------------------------------//
// Destructor.
STKMeshEntityLocalMap::~STKMeshEntityLocalMap()
{ /* ... */ }

//---------------------------------------------------------------------------//
// Return the entity measure with respect to the parameteric dimension (volume
// for a 3D entity, area for 2D, and length for 1D).
double STKMeshEntityLocalMap::measure( const Entity& entity ) const
{
    // Get the STK entity and its topology.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);
    shards::CellTopology entity_topo =
	stk::mesh::get_cell_topology(
	    d_bulk_data->bucket(stk_entity).topology() );

    // Get the STK entity coordinates.
    Intrepid::FieldContainer<double> entity_coords =
	STKMeshHelpers::getEntityNodeCoordinates(
	    Teuchos::Array<stk::mesh::Entity>(1,stk_entity), *d_bulk_data );

    // Compute the measure of the element.
    if ( rank == stk::topology::ELEM_RANK )
    {
	return IntrepidCellLocalMap::measure( entity_topo, entity_coords );
    }

    // Compute the measure of the face.
    else if ( rank == stk::topology::FACE_RANK )
    {
	bool not_implemented = true;
	DTK_INSIST( !not_implemented );
	return -1.0;
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
	return - 1.0;
    }
    return -1.0;
}

//---------------------------------------------------------------------------//
// Return the centroid of the entity.
void STKMeshEntityLocalMap::centroid(
    const Entity& entity, const Teuchos::ArrayView<double>& centroid ) const
{
    // Get the STK entity.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);

    // Extract the centroid of the element.
    if ( rank == stk::topology::ELEM_RANK )
    {
	shards::CellTopology entity_topo =
	    stk::mesh::get_cell_topology(
		d_bulk_data->bucket(stk_entity).topology() );
	Intrepid::FieldContainer<double> entity_coords =
	    STKMeshHelpers::getEntityNodeCoordinates(
		Teuchos::Array<stk::mesh::Entity>(1,stk_entity), *d_bulk_data );
	IntrepidCellLocalMap::centroid(
	    entity_topo, entity_coords, centroid );
    }

    // Extract the centroid of the face.
    else if ( rank == stk::topology::FACE_RANK )
    {
	bool not_implemented = true;
	DTK_INSIST( !not_implemented );
    }

    // The centroid of a node is the node coordinates.
    else if ( rank == stk::topology::NODE_RANK )
    {
	Intrepid::FieldContainer<double> entity_coords =
	    STKMeshHelpers::getEntityNodeCoordinates(
		Teuchos::Array<stk::mesh::Entity>(1,stk_entity), *d_bulk_data );
	centroid.assign( entity_coords.getData()() );
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
    }
}

//---------------------------------------------------------------------------//
// Perform a safeguard check for mapping a point to the reference space
// of an entity using the given tolerance.
bool STKMeshEntityLocalMap::isSafeToMapToReferenceFrame(
    const Entity& entity,
    const Teuchos::ArrayView<const double>& point,
    const Teuchos::RCP<MappingStatus>& status ) const
{
    // Get the STK entity.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);

    // If we have an element, use the default implementation.
    if ( rank == stk::topology::ELEM_RANK )
    {
	return
	    EntityLocalMap::isSafeToMapToReferenceFrame( entity, point, status );
    }

    // If we have a face, perform the projection safeguard.
    else if ( rank == stk::topology::FACE_RANK )
    {
	bool not_implemented = true;
	DTK_INSIST( !not_implemented );
	return false;
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
	return false;
    }

    // Return true to indicate successful mapping. Catching Intrepid errors
    // and returning false is a possibility here.
    return true;
}

//---------------------------------------------------------------------------//
// Map a point to the reference space of an entity. Return the parameterized
// point.
bool STKMeshEntityLocalMap::mapToReferenceFrame(
    const Entity& entity,
    const Teuchos::ArrayView<const double>& point,
    const Teuchos::ArrayView<double>& reference_point,
    const Teuchos::RCP<MappingStatus>& status ) const
{
    // Get the STK entity.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);

    // Use the cell to perform the element mapping.
    if ( rank == stk::topology::ELEM_RANK )
    {
	shards::CellTopology entity_topo =
	    stk::mesh::get_cell_topology(
		d_bulk_data->bucket(stk_entity).topology() );
	Intrepid::FieldContainer<double> entity_coords =
	    STKMeshHelpers::getEntityNodeCoordinates(
		Teuchos::Array<stk::mesh::Entity>(1,stk_entity), *d_bulk_data );
	IntrepidCellLocalMap::mapToReferenceFrame(
	    entity_topo, entity_coords, point, reference_point );
    }

    // Use the side cell to perform the face mapping.
    else if ( rank == stk::topology::FACE_RANK )
    {

    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
    }

    // Return true to indicate successful mapping. Catching Intrepid errors
    // and returning false is a possibility here.
    return true;
}

//---------------------------------------------------------------------------//
// Determine if a reference point is in the parameterized space of an entity.
bool STKMeshEntityLocalMap::checkPointInclusion(
    const Entity& entity,
    const Teuchos::ArrayView<const double>& reference_point ) const
{
    // Get the test tolerance.
    double tolerance = 1.0e-6;
    if ( Teuchos::nonnull(this->b_parameters) )
    {
	if ( this->b_parameters->isParameter("Point Inclusion Tolerance") )
	{
	    tolerance =
		this->b_parameters->get<double>("Point Inclusion Tolerance");
	}
    }

    // Get the STK entity and its topology.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);
    shards::CellTopology entity_topo =
	stk::mesh::get_cell_topology(
	    d_bulk_data->bucket(stk_entity).topology() );

    // Check point inclusion in the element.
    if ( rank == stk::topology::ELEM_RANK )
    {
	return IntrepidCellLocalMap::checkPointInclusion(
	    entity_topo, reference_point, tolerance );
    }

    // Check point inclusion in the face.
    else if ( rank == stk::topology::FACE_RANK )
    {
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
	return false;
    }

    return false;
}

//---------------------------------------------------------------------------//
// Map a reference point to the physical space of an entity.
void STKMeshEntityLocalMap::mapToPhysicalFrame(
    const Entity& entity,
    const Teuchos::ArrayView<const double>& reference_point,
    const Teuchos::ArrayView<double>& point ) const
{
    // Get the STK entity.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);

    // Map from the element.
    if ( rank == stk::topology::ELEM_RANK )
    {
	shards::CellTopology entity_topo =
	    stk::mesh::get_cell_topology(
		d_bulk_data->bucket(stk_entity).topology() );
	Intrepid::FieldContainer<double> entity_coords =
	    STKMeshHelpers::getEntityNodeCoordinates(
		Teuchos::Array<stk::mesh::Entity>(1,stk_entity), *d_bulk_data );
	return IntrepidCellLocalMap::mapToPhysicalFrame(
	    entity_topo, entity_coords, reference_point, point );
    }

    // Map from the face.
    else if ( rank == stk::topology::FACE_RANK )
    {
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
    }
}

//---------------------------------------------------------------------------//
// Compute the normal on a face (3D) or edge (2D) at a given reference point.
void STKMeshEntityLocalMap::normalAtReferencePoint(
    const Entity& entity,
    const Teuchos::ArrayView<double>& reference_point,
    const Teuchos::ArrayView<double>& normal ) const
{
    // Get the STK entity.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);

    // We can only compute normals for faces.
    if ( rank == stk::topology::FACE_RANK )
    {

    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
    }
}

//---------------------------------------------------------------------------//

} // end namespace DataTransferKit

//---------------------------------------------------------------------------//
// end DTK_STKMeshEntityLocalMap.cpp
//---------------------------------------------------------------------------//
<commit_msg>Adding default insists for STKMesh local map functions on faces.<commit_after>//---------------------------------------------------------------------------//
/*
  Copyright (c) 2014, Stuart R. Slattery
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:

  *: Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.

  *: Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.

  *: Neither the name of the Oak Ridge National Laboratory nor the
  names of its contributors may be used to endorse or promote products
  derived from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//---------------------------------------------------------------------------//
/*!
 * \brief DTK_STKMeshEntityLocalMap.cpp
 * \author Stuart R. Slattery
 * \brief Forward and reverse local mappings for entities.
 */
//---------------------------------------------------------------------------//

#include "DTK_STKMeshEntityLocalMap.hpp"
#include "DTK_STKMeshHelpers.hpp"
#include "DTK_IntrepidCellLocalMap.hpp"
#include "DTK_ProjectionPrimitives.hpp"
#include "DTK_DBC.hpp"

#include <Intrepid_FieldContainer.hpp>

#include <stk_mesh/base/MetaData.hpp>
#include <stk_mesh/base/Part.hpp>
#include <stk_mesh/base/Selector.hpp>
#include <stk_topology/topology.hpp>

namespace DataTransferKit
{
//---------------------------------------------------------------------------//
// Constructor.
STKMeshEntityLocalMap::STKMeshEntityLocalMap(
    const Teuchos::RCP<stk::mesh::BulkData>& bulk_data )
    : d_bulk_data( bulk_data )
{ /* ... */ }

//---------------------------------------------------------------------------//
// Destructor.
STKMeshEntityLocalMap::~STKMeshEntityLocalMap()
{ /* ... */ }

//---------------------------------------------------------------------------//
// Return the entity measure with respect to the parameteric dimension (volume
// for a 3D entity, area for 2D, and length for 1D).
double STKMeshEntityLocalMap::measure( const Entity& entity ) const
{
    // Get the STK entity and its topology.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);
    shards::CellTopology entity_topo =
	stk::mesh::get_cell_topology(
	    d_bulk_data->bucket(stk_entity).topology() );

    // Get the STK entity coordinates.
    Intrepid::FieldContainer<double> entity_coords =
	STKMeshHelpers::getEntityNodeCoordinates(
	    Teuchos::Array<stk::mesh::Entity>(1,stk_entity), *d_bulk_data );

    // Compute the measure of the element.
    if ( rank == stk::topology::ELEM_RANK )
    {
	return IntrepidCellLocalMap::measure( entity_topo, entity_coords );
    }

    // Compute the measure of the face.
    else if ( rank == stk::topology::FACE_RANK )
    {
	bool not_implemented = true;
	DTK_INSIST( !not_implemented );
	return -1.0;
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
	return - 1.0;
    }
    return -1.0;
}

//---------------------------------------------------------------------------//
// Return the centroid of the entity.
void STKMeshEntityLocalMap::centroid(
    const Entity& entity, const Teuchos::ArrayView<double>& centroid ) const
{
    // Get the STK entity.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);

    // Extract the centroid of the element.
    if ( rank == stk::topology::ELEM_RANK )
    {
	shards::CellTopology entity_topo =
	    stk::mesh::get_cell_topology(
		d_bulk_data->bucket(stk_entity).topology() );
	Intrepid::FieldContainer<double> entity_coords =
	    STKMeshHelpers::getEntityNodeCoordinates(
		Teuchos::Array<stk::mesh::Entity>(1,stk_entity), *d_bulk_data );
	IntrepidCellLocalMap::centroid(
	    entity_topo, entity_coords, centroid );
    }

    // Extract the centroid of the face.
    else if ( rank == stk::topology::FACE_RANK )
    {
	bool not_implemented = true;
	DTK_INSIST( !not_implemented );
    }

    // The centroid of a node is the node coordinates.
    else if ( rank == stk::topology::NODE_RANK )
    {
	Intrepid::FieldContainer<double> entity_coords =
	    STKMeshHelpers::getEntityNodeCoordinates(
		Teuchos::Array<stk::mesh::Entity>(1,stk_entity), *d_bulk_data );
	centroid.assign( entity_coords.getData()() );
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
    }
}

//---------------------------------------------------------------------------//
// Perform a safeguard check for mapping a point to the reference space
// of an entity using the given tolerance.
bool STKMeshEntityLocalMap::isSafeToMapToReferenceFrame(
    const Entity& entity,
    const Teuchos::ArrayView<const double>& point,
    const Teuchos::RCP<MappingStatus>& status ) const
{
    // Get the STK entity.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);

    // If we have an element, use the default implementation.
    if ( rank == stk::topology::ELEM_RANK )
    {
	return
	    EntityLocalMap::isSafeToMapToReferenceFrame( entity, point, status );
    }

    // If we have a face, perform the projection safeguard.
    else if ( rank == stk::topology::FACE_RANK )
    {
	bool not_implemented = true;
	DTK_INSIST( !not_implemented );
	return false;
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
	return false;
    }

    // Return true to indicate successful mapping. Catching Intrepid errors
    // and returning false is a possibility here.
    return true;
}

//---------------------------------------------------------------------------//
// Map a point to the reference space of an entity. Return the parameterized
// point.
bool STKMeshEntityLocalMap::mapToReferenceFrame(
    const Entity& entity,
    const Teuchos::ArrayView<const double>& point,
    const Teuchos::ArrayView<double>& reference_point,
    const Teuchos::RCP<MappingStatus>& status ) const
{
    // Get the STK entity.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);

    // Use the cell to perform the element mapping.
    if ( rank == stk::topology::ELEM_RANK )
    {
	shards::CellTopology entity_topo =
	    stk::mesh::get_cell_topology(
		d_bulk_data->bucket(stk_entity).topology() );
	Intrepid::FieldContainer<double> entity_coords =
	    STKMeshHelpers::getEntityNodeCoordinates(
		Teuchos::Array<stk::mesh::Entity>(1,stk_entity), *d_bulk_data );
	IntrepidCellLocalMap::mapToReferenceFrame(
	    entity_topo, entity_coords, point, reference_point );
    }

    // Use the side cell to perform the face mapping.
    else if ( rank == stk::topology::FACE_RANK )
    {
	bool not_implemented = true;
	DTK_INSIST( !not_implemented );
	return false;
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
    }

    // Return true to indicate successful mapping. Catching Intrepid errors
    // and returning false is a possibility here.
    return true;
}

//---------------------------------------------------------------------------//
// Determine if a reference point is in the parameterized space of an entity.
bool STKMeshEntityLocalMap::checkPointInclusion(
    const Entity& entity,
    const Teuchos::ArrayView<const double>& reference_point ) const
{
    // Get the test tolerance.
    double tolerance = 1.0e-6;
    if ( Teuchos::nonnull(this->b_parameters) )
    {
	if ( this->b_parameters->isParameter("Point Inclusion Tolerance") )
	{
	    tolerance =
		this->b_parameters->get<double>("Point Inclusion Tolerance");
	}
    }

    // Get the STK entity and its topology.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);
    shards::CellTopology entity_topo =
	stk::mesh::get_cell_topology(
	    d_bulk_data->bucket(stk_entity).topology() );

    // Check point inclusion in the element.
    if ( rank == stk::topology::ELEM_RANK )
    {
	return IntrepidCellLocalMap::checkPointInclusion(
	    entity_topo, reference_point, tolerance );
    }

    // Check point inclusion in the face.
    else if ( rank == stk::topology::FACE_RANK )
    {
	bool not_implemented = true;
	DTK_INSIST( !not_implemented );
	return false;
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
	return false;
    }

    return false;
}

//---------------------------------------------------------------------------//
// Map a reference point to the physical space of an entity.
void STKMeshEntityLocalMap::mapToPhysicalFrame(
    const Entity& entity,
    const Teuchos::ArrayView<const double>& reference_point,
    const Teuchos::ArrayView<double>& point ) const
{
    // Get the STK entity.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);

    // Map from the element.
    if ( rank == stk::topology::ELEM_RANK )
    {
	shards::CellTopology entity_topo =
	    stk::mesh::get_cell_topology(
		d_bulk_data->bucket(stk_entity).topology() );
	Intrepid::FieldContainer<double> entity_coords =
	    STKMeshHelpers::getEntityNodeCoordinates(
		Teuchos::Array<stk::mesh::Entity>(1,stk_entity), *d_bulk_data );
	IntrepidCellLocalMap::mapToPhysicalFrame(
	    entity_topo, entity_coords, reference_point, point );
    }

    // Map from the face.
    else if ( rank == stk::topology::FACE_RANK )
    {
	bool not_implemented = true;
	DTK_INSIST( !not_implemented );
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
    }
}

//---------------------------------------------------------------------------//
// Compute the normal on a face (3D) or edge (2D) at a given reference point.
void STKMeshEntityLocalMap::normalAtReferencePoint(
    const Entity& entity,
    const Teuchos::ArrayView<double>& reference_point,
    const Teuchos::ArrayView<double>& normal ) const
{
    // Get the STK entity.
    const stk::mesh::Entity& stk_entity = STKMeshHelpers::extractEntity(entity);
    stk::mesh::EntityRank rank = d_bulk_data->entity_rank(stk_entity);

    // We can only compute normals for faces.
    if ( rank == stk::topology::FACE_RANK )
    {
	bool not_implemented = true;
	DTK_INSIST( !not_implemented );
    }

    // Check for unsupported ranks.
    else
    {
	bool bad_rank = true;
	DTK_INSIST( !bad_rank );
    }
}

//---------------------------------------------------------------------------//

} // end namespace DataTransferKit

//---------------------------------------------------------------------------//
// end DTK_STKMeshEntityLocalMap.cpp
//---------------------------------------------------------------------------//
<|endoftext|>