<commit_before>/*
Remove all elements from a linked list of integers that have value val.

Example
Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
Return: 1 --> 2 --> 3 --> 4 --> 5

Credits:
Special thanks to @mithmatt for adding this problem and creating all test cases.
*/

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

#include <stdio.h>

struct ListNode {
	int val;
 	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};

void print_list(ListNode *list) {
	for ( ; list != NULL; list = list->next) {
		printf("%d->", list->val);
	}
	printf("NULL\n");
}

class Solution {
public:
	// 1->2->3->4->5->NULL
	// 1->2->4->5->NULL
    ListNode* removeElements(ListNode* head, int val) {
		ListNode* p = head;
		ListNode* q = head;
		ListNode* s = head;
		ListNode* result = NULL;
		if (head == NULL) {
			return result;
		}
		if (head->next == NULL && head->val == val) {
			return result;
		}

		result = head;
		for ( ; p != NULL; ) {
			if (p->val != val ) {
				break;
			}
			result = p->next;
			p = p->next;
		}

		if (result == NULL) {
			return result;
		}

		p = head;
		for ( ; p->next != NULL; ) {
			q = p;
			p = p->next;

			if (p->val == val) {
				q->next = p->next;
				p = q;
			}
		}

		if (p->val == val) {
			q->next = NULL;
		}

		if (head->val == val) {
			result = head->next;
		}

		return result;
    }
};

int main() {
	ListNode l1(1), l2(2), l3(3);
	ListNode l4(4), l5(5), l6(6), l7(6), l8(6), l9(9), l10(10), l11(11), l12(12), l13(6);
	ListNode n1(0), n2(0), n3(0), n4(1);
	l1.next = &l2;
	l2.next = &l3;

	l4.next = &l5;
	l5.next = &l6;
	l6.next = &l7;
	l7.next = &l8;
	l8.next = &l9;
	l9.next = &l10;
	l10.next = &l11;
	l11.next = &l12;
	l12.next = &l13;

//	n1.next = &n2;
//	n2.next = &n3;
	//n3.next = &n4;

	print_list(&l4);
	Solution s;
	print_list(s.removeElements(&l4, 6));
	return 0;
}
<commit_msg>add comments<commit_after>/*
Remove all elements from a linked list of integers that have value val.

Example
Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
Return: 1 --> 2 --> 3 --> 4 --> 5

Credits:
Special thanks to @mithmatt for adding this problem and creating all test cases.
*/

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

#include <stdio.h>

struct ListNode {
	int val;
 	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};

void print_list(ListNode *list) {
	for ( ; list != NULL; list = list->next) {
		printf("%d->", list->val);
	}
	printf("NULL\n");
}

class Solution {
public:
	// 1->2->3->4->5->NULL
	// 1->2->4->5->NULL
    ListNode* removeElements(ListNode* head, int val) {
		ListNode* p = head;
		ListNode* q = head;
		ListNode* s = head;
		ListNode* result = NULL;
		if (head == NULL) {
			return result;
		}
		if (head->next == NULL && head->val == val) {
			return result;
		}

		result = head;
		for ( ; p != NULL; ) {
			if (p->val != val ) {
				break;
			}
			result = p->next;
			p = p->next;
		}

		if (result == NULL) {
			return result;
		}

		p = head;
		for ( ; p->next != NULL; ) {
			q = p;
			p = p->next;

			if (p->val == val) {
				q->next = p->next;
				p = q;
			}
		}

		if (p->val == val) {
			q->next = NULL;
		}

		if (head->val == val) {
			result = head->next;
		}

		return result;
    }
};

int main() {
	ListNode l1(1), l2(2), l3(3);
	ListNode l4(4), l5(5), l6(6), l7(6), l8(6), l9(9), l10(10), l11(11), l12(12), l13(6);
	ListNode n1(0), n2(0), n3(0), n4(1);
	l1.next = &l2;
	l2.next = &l3;

	l4.next = &l5;
	l5.next = &l6;
	l6.next = &l7;
	l7.next = &l8;
	l8.next = &l9;
	l9.next = &l10;
	l10.next = &l11;
	l11.next = &l12;
	l12.next = &l13;

	//n1.next = &n2;
	//n2.next = &n3;
	//n3.next = &n4;

	print_list(&l4);
	Solution s;
	print_list(s.removeElements(&l4, 6));
	return 0;
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// object that creates and contains a spawn position

#include "common.h"

#include "SpawnPosition.h"
#include "FlagInfo.h"
#include "TeamBases.h"
#include "WorldInfo.h"
#include "PlayerInfo.h"
#include "PlayerState.h"

// FIXME: from bzfs.cxx
extern int getCurMaxPlayers();
extern bool areFoes(TeamColor team1, TeamColor team2);
extern BasesList bases;
extern WorldInfo *world;
extern PlayerInfo player[];
extern PlayerState lastState[];

SpawnPosition::SpawnPosition(int playerId, bool onGroundOnly, bool notNearEdges) :
		curMaxPlayers(getCurMaxPlayers())
{
  team = player[playerId].getTeam();
  azimuth = (float)bzfrand() * 2.0f * M_PI;

  if (player[playerId].shouldRestartAtBase() &&
      (team >= RedTeam) && (team <= PurpleTeam) &&
      (bases.find(team) != bases.end())) {
    TeamBases &teamBases = bases[team];
    const TeamBase &base = teamBases.getRandomBase((int)(bzfrand() * 100));
    base.getRandomPosition(pos[0], pos[1], pos[2]);
    player[playerId].setRestartOnBase(false);
  } else {
    const float tankHeight = BZDB.eval(StateDatabase::BZDB_TANKHEIGHT);
    const float tankRadius = BZDB.eval(StateDatabase::BZDB_TANKRADIUS);
    safeSWRadius = (float)((BZDB.eval(StateDatabase::BZDB_SHOCKOUTRADIUS) + BZDB.eval(StateDatabase::BZDB_TANKRADIUS)) * 1.5);
    safeDistance = tankRadius * 20; // FIXME: is this a good value?
    const float size = BZDB.eval(StateDatabase::BZDB_WORLDSIZE);
    const float maxWorldHeight = world->getMaxWorldHeight();
    ObstacleLocation *building;

    // keep track of how much time we spend searching for a location
    TimeKeeper start = TimeKeeper::getCurrent();

    int inAirAttempts = 50;
    int tries = 0;
    float minProximity = size / 3.0f;
    float bestDist = -1.0f;
    bool foundspot = false;
    while (!foundspot) {
      if (!world->getZonePoint(std::string(Team::getName(team)), testPos)) {
        if (notNearEdges) {
          // don't spawn close to map edges in CTF mode
          testPos[0] = ((float)bzfrand() - 0.5f) * size * 0.6f;
          testPos[1] = ((float)bzfrand() - 0.5f) * size * 0.6f;
	} else {
          testPos[0] = ((float)bzfrand() - 0.5f) * (size - 2.0f * tankRadius);
          testPos[1] = ((float)bzfrand() - 0.5f) * (size - 2.0f * tankRadius);
	}
        testPos[2] = onGroundOnly ? 0.0f : ((float)bzfrand() * maxWorldHeight);
      }
      tries++;

      int type = world->inBuilding(&building, testPos[0], testPos[1], testPos[2],
                                   tankRadius, tankHeight);

      if (onGroundOnly) {
        if (type == NOT_IN_BUILDING)
          foundspot = true;
      } else {
        if ((type == NOT_IN_BUILDING) && (testPos[2] > 0.0f)) {
          testPos[2] = 0.0f;
          //Find any intersection regardless of z
          type = world->inBuilding(&building, testPos[0], testPos[1], testPos[2],
                                   tankRadius, maxWorldHeight);
        }

        // in a building? try climbing on roof until on top
        int lastType = type;
	int retriesRemaining = 100; // don't climb forever
        while (type != NOT_IN_BUILDING) {
          testPos[2] = building->pos[2] + building->size[2] + 0.0001f;
          tries++;
          lastType = type;
          type = world->inBuilding(&building, testPos[0], testPos[1], testPos[2],
                                   tankRadius, tankHeight);
	  if (--retriesRemaining <= 0) {
	    DEBUG1("Warning: getSpawnLocation had to climb too many buildings\n");
	    break;
	  }
        }
        // ok, when not on top of pyramid or teleporter
        if (lastType != IN_PYRAMID  &&  lastType != IN_TELEPORTER) {
          foundspot = true;
        }
        // only try up in the sky so many times
        if (--inAirAttempts <= 0) {
          onGroundOnly = true;
        }
      }

      // check every now and then if we have already used up 10ms of time
      if (tries >= 50) {
        tries = 0;
        if (TimeKeeper::getCurrent() - start > 0.01f) {
          if (bestDist < 0.0f) { // haven't found a single spot
            //Just drop the sucka in, and pray
            pos[0] = testPos[0];
            pos[1] = testPos[1];
            pos[2] = maxWorldHeight;
	    DEBUG1("Warning: getSpawnLocation ran out of time, just dropping the sucker in\n");
          }
          break;
        }
      }

      // check if spot is safe enough
      bool dangerous = isImminentlyDangerous();
      if (foundspot && !dangerous) {
	float enemyAngle;
	float dist = enemyProximityCheck(enemyAngle);
	if (dist > bestDist) { // best so far
	  bestDist = dist;
	  pos[0] = testPos[0];
	  pos[1] = testPos[1];
	  pos[2] = testPos[2];
	  azimuth = fmod((enemyAngle + M_PI), 2.0f * M_PI);
	}
	if (bestDist < minProximity) { // not good enough, keep looking
	  foundspot = false;
	  minProximity *= 0.99f; // relax requirements a little
	}
      } else if (dangerous) {
	foundspot = false;
      }
    }
    delete building;
  }
}

SpawnPosition::~SpawnPosition()
{
}

const bool SpawnPosition::isFacing(const float *enemyPos, const float enemyAzimuth,
				   const float deviation) const
{
  // determine angle from source to dest
  // (X) using only x & y, resultant will be z rotation
  float dx = testPos[0] - enemyPos[0];
  float dy = testPos[1] - enemyPos[1];
  float angActual;
  if (dx == 0) {
    // avoid divide by zero error
    angActual = (float)tan(dy / (1 / 1e12f));
  } else {
    angActual = (float)tan(dy / dx);
  }

  // see if our heading angle is within the bounds set by deviation
  // (X) only compare to z-rotation since that's all we're using
  if (((angActual + deviation / 2) > enemyAzimuth) &&
      ((angActual - deviation / 2) < enemyAzimuth)) {
    return true;
  } else {
    return false;
  }
}

const bool SpawnPosition::isImminentlyDangerous() const
{
  for (int i = 0; i < curMaxPlayers; i++) {
    if (player[i].isAlive() && areFoes(player[i].getTeam(), team)) {
      const FlagInfo *finfo =&flag[player[i].getFlag()];
      const FlagType *ftype = finfo->flag.type;
      float *enemyPos = lastState[i].pos;
      float enemyAngle = lastState[i].azimuth;
      // check for dangerous flags, etc
      // FIXME: any more?
      if (ftype == Flags::Laser) {  // don't spawn in the line of sight of an L
	if (isFacing(enemyPos, enemyAngle, M_PI / 9)) { // he's looking within 20 degrees of spawn point
	  return true;	// eek, don't spawn here
	}
      } else if (ftype == Flags::ShockWave) {  // don't spawn next to a SW
	if (distanceFrom(enemyPos) < safeSWRadius) { // too close to SW
	  return true;	// eek, don't spawn here
	}
      }
      // don't spawn in the line of sight of a normal-shot tank within a certain distance
      if (distanceFrom(enemyPos) < safeDistance) { // within danger zone?
	if (isFacing(enemyPos, enemyAngle, M_PI / 9)) { //and he's looking at me
	  return true;
	}
      }
    }
  }

  // TODO: should check world weapons also

  return false;
}

const float SpawnPosition::enemyProximityCheck(float &enemyAngle) const
{
  float worstDist = 1e12f; // huge number
  bool noEnemy    = true;

  for (int i = 0; i < curMaxPlayers; i++) {
    if (player[i].isAlive() && areFoes(player[i].getTeam(), team)) {
      float *enemyPos = lastState[i].pos;
      if (fabs(enemyPos[2] - testPos[2]) < 1.0f) {
        float x = enemyPos[0] - testPos[0];
        float y = enemyPos[1] - testPos[1];
        float distSq = x * x + y * y;
        if (distSq < worstDist) {
          worstDist  = distSq;
	  enemyAngle = lastState[i].azimuth;
	  noEnemy    = false;
	}
      }
    }
  }
  if (noEnemy)
    enemyAngle = (float)bzfrand() * 2.0f * M_PI;
  return sqrtf(worstDist);
}

const float SpawnPosition::distanceFrom(const float* farPos) const
{
  float dx = farPos[0] - testPos[0];
  float dy = farPos[1] - testPos[1];
  float dz = farPos[2] - testPos[2];
  return (float)sqrt(dx*dx + dy*dy + dz*dz);
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>and the next one - don't delete building if it was never initialized<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// object that creates and contains a spawn position

#include "common.h"

#include "SpawnPosition.h"
#include "FlagInfo.h"
#include "TeamBases.h"
#include "WorldInfo.h"
#include "PlayerInfo.h"
#include "PlayerState.h"

// FIXME: from bzfs.cxx
extern int getCurMaxPlayers();
extern bool areFoes(TeamColor team1, TeamColor team2);
extern BasesList bases;
extern WorldInfo *world;
extern PlayerInfo player[];
extern PlayerState lastState[];

SpawnPosition::SpawnPosition(int playerId, bool onGroundOnly, bool notNearEdges) :
		curMaxPlayers(getCurMaxPlayers())
{
  team = player[playerId].getTeam();
  azimuth = (float)bzfrand() * 2.0f * M_PI;

  if (player[playerId].shouldRestartAtBase() &&
      (team >= RedTeam) && (team <= PurpleTeam) &&
      (bases.find(team) != bases.end())) {
    TeamBases &teamBases = bases[team];
    const TeamBase &base = teamBases.getRandomBase((int)(bzfrand() * 100));
    base.getRandomPosition(pos[0], pos[1], pos[2]);
    player[playerId].setRestartOnBase(false);
  } else {
    const float tankHeight = BZDB.eval(StateDatabase::BZDB_TANKHEIGHT);
    const float tankRadius = BZDB.eval(StateDatabase::BZDB_TANKRADIUS);
    safeSWRadius = (float)((BZDB.eval(StateDatabase::BZDB_SHOCKOUTRADIUS) + BZDB.eval(StateDatabase::BZDB_TANKRADIUS)) * 1.5);
    safeDistance = tankRadius * 20; // FIXME: is this a good value?
    const float size = BZDB.eval(StateDatabase::BZDB_WORLDSIZE);
    const float maxWorldHeight = world->getMaxWorldHeight();
    ObstacleLocation *building = NULL;

    // keep track of how much time we spend searching for a location
    TimeKeeper start = TimeKeeper::getCurrent();

    int inAirAttempts = 50;
    int tries = 0;
    float minProximity = size / 3.0f;
    float bestDist = -1.0f;
    bool foundspot = false;
    while (!foundspot) {
      if (!world->getZonePoint(std::string(Team::getName(team)), testPos)) {
        if (notNearEdges) {
          // don't spawn close to map edges in CTF mode
          testPos[0] = ((float)bzfrand() - 0.5f) * size * 0.6f;
          testPos[1] = ((float)bzfrand() - 0.5f) * size * 0.6f;
	} else {
          testPos[0] = ((float)bzfrand() - 0.5f) * (size - 2.0f * tankRadius);
          testPos[1] = ((float)bzfrand() - 0.5f) * (size - 2.0f * tankRadius);
	}
        testPos[2] = onGroundOnly ? 0.0f : ((float)bzfrand() * maxWorldHeight);
      }
      tries++;

      int type = world->inBuilding(&building, testPos[0], testPos[1], testPos[2],
                                   tankRadius, tankHeight);

      if (onGroundOnly) {
        if (type == NOT_IN_BUILDING)
          foundspot = true;
      } else {
        if ((type == NOT_IN_BUILDING) && (testPos[2] > 0.0f)) {
          testPos[2] = 0.0f;
          //Find any intersection regardless of z
          type = world->inBuilding(&building, testPos[0], testPos[1], testPos[2],
                                   tankRadius, maxWorldHeight);
        }

        // in a building? try climbing on roof until on top
        int lastType = type;
	int retriesRemaining = 100; // don't climb forever
        while (type != NOT_IN_BUILDING) {
          testPos[2] = building->pos[2] + building->size[2] + 0.0001f;
          tries++;
          lastType = type;
          type = world->inBuilding(&building, testPos[0], testPos[1], testPos[2],
                                   tankRadius, tankHeight);
	  if (--retriesRemaining <= 0) {
	    DEBUG1("Warning: getSpawnLocation had to climb too many buildings\n");
	    break;
	  }
        }
        // ok, when not on top of pyramid or teleporter
        if (lastType != IN_PYRAMID  &&  lastType != IN_TELEPORTER) {
          foundspot = true;
        }
        // only try up in the sky so many times
        if (--inAirAttempts <= 0) {
          onGroundOnly = true;
        }
      }

      // check every now and then if we have already used up 10ms of time
      if (tries >= 50) {
        tries = 0;
        if (TimeKeeper::getCurrent() - start > 0.01f) {
          if (bestDist < 0.0f) { // haven't found a single spot
            //Just drop the sucka in, and pray
            pos[0] = testPos[0];
            pos[1] = testPos[1];
            pos[2] = maxWorldHeight;
	    DEBUG1("Warning: getSpawnLocation ran out of time, just dropping the sucker in\n");
          }
          break;
        }
      }

      // check if spot is safe enough
      bool dangerous = isImminentlyDangerous();
      if (foundspot && !dangerous) {
	float enemyAngle;
	float dist = enemyProximityCheck(enemyAngle);
	if (dist > bestDist) { // best so far
	  bestDist = dist;
	  pos[0] = testPos[0];
	  pos[1] = testPos[1];
	  pos[2] = testPos[2];
	  azimuth = fmod((enemyAngle + M_PI), 2.0f * M_PI);
	}
	if (bestDist < minProximity) { // not good enough, keep looking
	  foundspot = false;
	  minProximity *= 0.99f; // relax requirements a little
	}
      } else if (dangerous) {
	foundspot = false;
      }
    }
    if (!(building == NULL))
      delete building;
  }
}

SpawnPosition::~SpawnPosition()
{
}

const bool SpawnPosition::isFacing(const float *enemyPos, const float enemyAzimuth,
				   const float deviation) const
{
  // determine angle from source to dest
  // (X) using only x & y, resultant will be z rotation
  float dx = testPos[0] - enemyPos[0];
  float dy = testPos[1] - enemyPos[1];
  float angActual;
  if (dx == 0) {
    // avoid divide by zero error
    angActual = (float)tan(dy / (1 / 1e12f));
  } else {
    angActual = (float)tan(dy / dx);
  }

  // see if our heading angle is within the bounds set by deviation
  // (X) only compare to z-rotation since that's all we're using
  if (((angActual + deviation / 2) > enemyAzimuth) &&
      ((angActual - deviation / 2) < enemyAzimuth)) {
    return true;
  } else {
    return false;
  }
}

const bool SpawnPosition::isImminentlyDangerous() const
{
  for (int i = 0; i < curMaxPlayers; i++) {
    if (player[i].isAlive() && areFoes(player[i].getTeam(), team)) {
      const FlagInfo *finfo =&flag[player[i].getFlag()];
      const FlagType *ftype = finfo->flag.type;
      float *enemyPos = lastState[i].pos;
      float enemyAngle = lastState[i].azimuth;
      // check for dangerous flags, etc
      // FIXME: any more?
      if (ftype == Flags::Laser) {  // don't spawn in the line of sight of an L
	if (isFacing(enemyPos, enemyAngle, M_PI / 9)) { // he's looking within 20 degrees of spawn point
	  return true;	// eek, don't spawn here
	}
      } else if (ftype == Flags::ShockWave) {  // don't spawn next to a SW
	if (distanceFrom(enemyPos) < safeSWRadius) { // too close to SW
	  return true;	// eek, don't spawn here
	}
      }
      // don't spawn in the line of sight of a normal-shot tank within a certain distance
      if (distanceFrom(enemyPos) < safeDistance) { // within danger zone?
	if (isFacing(enemyPos, enemyAngle, M_PI / 9)) { //and he's looking at me
	  return true;
	}
      }
    }
  }

  // TODO: should check world weapons also

  return false;
}

const float SpawnPosition::enemyProximityCheck(float &enemyAngle) const
{
  float worstDist = 1e12f; // huge number
  bool noEnemy    = true;

  for (int i = 0; i < curMaxPlayers; i++) {
    if (player[i].isAlive() && areFoes(player[i].getTeam(), team)) {
      float *enemyPos = lastState[i].pos;
      if (fabs(enemyPos[2] - testPos[2]) < 1.0f) {
        float x = enemyPos[0] - testPos[0];
        float y = enemyPos[1] - testPos[1];
        float distSq = x * x + y * y;
        if (distSq < worstDist) {
          worstDist  = distSq;
	  enemyAngle = lastState[i].azimuth;
	  noEnemy    = false;
	}
      }
    }
  }
  if (noEnemy)
    enemyAngle = (float)bzfrand() * 2.0f * M_PI;
  return sqrtf(worstDist);
}

const float SpawnPosition::distanceFrom(const float* farPos) const
{
  float dx = farPos[0] - testPos[0];
  float dy = farPos[1] - testPos[1];
  float dz = farPos[2] - testPos[2];
  return (float)sqrt(dx*dx + dy*dy + dz*dz);
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2014 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreShaderPrecompiledHeaders.h"

namespace Ogre {
namespace RTShader {

//-----------------------------------------------------------------------------
SGScriptTranslator::SGScriptTranslator() :
    mGeneratedRenderState(NULL)
{
}

//-----------------------------------------------------------------------------
void SGScriptTranslator::translate(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
    ObjectAbstractNode* obj = static_cast<ObjectAbstractNode*>(node.get());
    ObjectAbstractNode* parent = static_cast<ObjectAbstractNode*>(obj->parent);

    // Translate section within a pass context.
    if (parent->id == ID_PASS)
    {
        translatePass(compiler, node);
    }
    if (parent->id == ID_TEXTURE_UNIT)
    {
        translateTextureUnit(compiler, node);
    }
}

//-----------------------------------------------------------------------------
SubRenderState* SGScriptTranslator::getGeneratedSubRenderState(const String& typeName)
{
    //check if we are in the middle of parsing
    if (mGeneratedRenderState)
    {
        /** Get the list of the template sub render states composing this render state. */
        const SubRenderStateList& rsList =
            mGeneratedRenderState->getTemplateSubRenderStateList();

        SubRenderStateList::const_iterator it = rsList.begin();
        SubRenderStateList::const_iterator itEnd = rsList.end();
        for(; it != itEnd; ++it)
        {
            if ((*it)->getType() == typeName)
                return *it;
        }
    }
    return NULL;
}

//-----------------------------------------------------------------------------
/*
note: we can know the texture unit index by getting parent then finding it in the list of children
*/
void SGScriptTranslator::translateTextureUnit(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
    ObjectAbstractNode *obj = static_cast<ObjectAbstractNode*>(node.get());
    TextureUnitState* texState = any_cast<TextureUnitState*>(obj->parent->context);
    Pass* pass = texState->getParent();
    Technique* technique = pass->getParent();
    Material* material = technique->getParent();
    ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr();
    String dstTechniqueSchemeName = obj->name;
    bool techniqueCreated;

    // Make sure the scheme name is valid - use default if none exists.
    if (dstTechniqueSchemeName.empty())
        dstTechniqueSchemeName = ShaderGenerator::DEFAULT_SCHEME_NAME;

    //check if technique already created
    techniqueCreated = shaderGenerator->hasShaderBasedTechnique(material->getName(),
        material->getGroup(),
        technique->getSchemeName(),
        dstTechniqueSchemeName);

    if (techniqueCreated == false)
    {
        // Create the shader based technique.
        techniqueCreated = shaderGenerator->createShaderBasedTechnique(technique,
            dstTechniqueSchemeName,
            shaderGenerator->getCreateShaderOverProgrammablePass());
    }

    // Case technique successfully created.
    if (techniqueCreated)
    {
        //Attempt to get the render state which might have been created by the pass parsing
        mGeneratedRenderState = shaderGenerator->getRenderState(dstTechniqueSchemeName,
                    material->getName(), material->getGroup(), pass->getIndex());

        // Go over all the render state properties.
        for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i)
        {
            if((*i)->type == ANT_PROPERTY)
            {
                PropertyAbstractNode *prop = static_cast<PropertyAbstractNode*>((*i).get());
                SubRenderState* subRenderState = ShaderGenerator::getSingleton().createSubRenderState(compiler, prop, texState, this);

                if (subRenderState)
                {
                    addSubRenderState(subRenderState, dstTechniqueSchemeName, material->getName(),
                        material->getGroup(), pass->getIndex());
                }
            }
            else
            {
                processNode(compiler, *i);
            }
        }

        mGeneratedRenderState = NULL;
    }
}

//-----------------------------------------------------------------------------
void SGScriptTranslator::translatePass(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
    ObjectAbstractNode *obj = static_cast<ObjectAbstractNode*>(node.get());
    Pass* pass = any_cast<Pass*>(obj->parent->context);
    Technique* technique = pass->getParent();
    Material* material = technique->getParent();
    ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr();
    String dstTechniqueSchemeName = obj->name;
    bool techniqueCreated;

    // Make sure the scheme name is valid - use default if none exists.
    if (dstTechniqueSchemeName.empty())
        dstTechniqueSchemeName = ShaderGenerator::DEFAULT_SCHEME_NAME;

    // Create the shader based technique.
    techniqueCreated = shaderGenerator->createShaderBasedTechnique(technique,
        dstTechniqueSchemeName,
        shaderGenerator->getCreateShaderOverProgrammablePass());

    // Case technique successfully created.
    if (techniqueCreated)
    {
        // Go over all the render state properties.
        for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i)
        {
            if((*i)->type == ANT_PROPERTY)
            {
                PropertyAbstractNode *prop = static_cast<PropertyAbstractNode*>((*i).get());

                // Handle light count property.
                if (prop->name == "light_count")
                {
                    if (prop->values.size() != 3)
                    {
                        compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    }
                    else
                    {
                        std::vector<int> lightCount;
                        if (getVector(prop->values.begin(), prop->values.end(), lightCount, 3))
                        {
                            shaderGenerator->createScheme(dstTechniqueSchemeName);
                            RenderState* renderState = shaderGenerator->getRenderState(dstTechniqueSchemeName,
                                material->getName(), material->getGroup(), pass->getIndex());

                            renderState->setLightCount(Vector3i(lightCount.data()));
                            renderState->setLightCountAutoUpdate(false);
                        }
                        else
                        {
                            compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                        }
                    }
                }

                // Handle the rest of the custom properties.
                else
                {
                    SubRenderState* subRenderState = ShaderGenerator::getSingleton().createSubRenderState(compiler, prop, pass, this);
                    if (subRenderState)
                    {
                        addSubRenderState(subRenderState, dstTechniqueSchemeName, material->getName(), material->getGroup(), pass->getIndex());
                    }
                }
            }
            else
            {
                processNode(compiler, *i);
            }
        }

        mGeneratedRenderState = NULL;
    }

}

//-----------------------------------------------------------------------------
void SGScriptTranslator::addSubRenderState(SubRenderState* newSubRenderState,
        const String& dstTechniqueSchemeName, const String& materialName, const String& groupName, unsigned short passIndex)
{
    assert(newSubRenderState);

    //check if a different sub render state of the same type already exists
    ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr();

    //create a new scheme if needed
    shaderGenerator->createScheme(dstTechniqueSchemeName);

    //update the active render state
    mGeneratedRenderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, materialName, groupName, passIndex);

    //add the new sub render state
    mGeneratedRenderState->addTemplateSubRenderState(newSubRenderState);
}

}
}
<commit_msg>RTSS: ScriptTranslator - log error when encountering unknown parameter<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2014 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreShaderPrecompiledHeaders.h"

namespace Ogre {
namespace RTShader {

//-----------------------------------------------------------------------------
SGScriptTranslator::SGScriptTranslator() :
    mGeneratedRenderState(NULL)
{
}

//-----------------------------------------------------------------------------
void SGScriptTranslator::translate(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
    ObjectAbstractNode* obj = static_cast<ObjectAbstractNode*>(node.get());
    ObjectAbstractNode* parent = static_cast<ObjectAbstractNode*>(obj->parent);

    // Translate section within a pass context.
    if (parent->id == ID_PASS)
    {
        translatePass(compiler, node);
    }
    if (parent->id == ID_TEXTURE_UNIT)
    {
        translateTextureUnit(compiler, node);
    }
}

//-----------------------------------------------------------------------------
SubRenderState* SGScriptTranslator::getGeneratedSubRenderState(const String& typeName)
{
    //check if we are in the middle of parsing
    if (mGeneratedRenderState)
    {
        /** Get the list of the template sub render states composing this render state. */
        const SubRenderStateList& rsList =
            mGeneratedRenderState->getTemplateSubRenderStateList();

        SubRenderStateList::const_iterator it = rsList.begin();
        SubRenderStateList::const_iterator itEnd = rsList.end();
        for(; it != itEnd; ++it)
        {
            if ((*it)->getType() == typeName)
                return *it;
        }
    }
    return NULL;
}

//-----------------------------------------------------------------------------
/*
note: we can know the texture unit index by getting parent then finding it in the list of children
*/
void SGScriptTranslator::translateTextureUnit(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
    ObjectAbstractNode *obj = static_cast<ObjectAbstractNode*>(node.get());
    TextureUnitState* texState = any_cast<TextureUnitState*>(obj->parent->context);
    Pass* pass = texState->getParent();
    Technique* technique = pass->getParent();
    Material* material = technique->getParent();
    ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr();
    String dstTechniqueSchemeName = obj->name;
    bool techniqueCreated;

    // Make sure the scheme name is valid - use default if none exists.
    if (dstTechniqueSchemeName.empty())
        dstTechniqueSchemeName = ShaderGenerator::DEFAULT_SCHEME_NAME;

    //check if technique already created
    techniqueCreated = shaderGenerator->hasShaderBasedTechnique(material->getName(),
        material->getGroup(),
        technique->getSchemeName(),
        dstTechniqueSchemeName);

    if (techniqueCreated == false)
    {
        // Create the shader based technique.
        techniqueCreated = shaderGenerator->createShaderBasedTechnique(technique,
            dstTechniqueSchemeName,
            shaderGenerator->getCreateShaderOverProgrammablePass());
    }

    // Case technique successfully created.
    if (techniqueCreated)
    {
        //Attempt to get the render state which might have been created by the pass parsing
        mGeneratedRenderState = shaderGenerator->getRenderState(dstTechniqueSchemeName,
                    material->getName(), material->getGroup(), pass->getIndex());

        // Go over all the render state properties.
        for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i)
        {
            if((*i)->type == ANT_PROPERTY)
            {
                PropertyAbstractNode *prop = static_cast<PropertyAbstractNode*>((*i).get());
                SubRenderState* subRenderState = ShaderGenerator::getSingleton().createSubRenderState(compiler, prop, texState, this);

                if (subRenderState)
                {
                    addSubRenderState(subRenderState, dstTechniqueSchemeName, material->getName(),
                        material->getGroup(), pass->getIndex());
                }
                else
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, prop->name);
                }
            }
            else
            {
                processNode(compiler, *i);
            }
        }

        mGeneratedRenderState = NULL;
    }
}

//-----------------------------------------------------------------------------
void SGScriptTranslator::translatePass(ScriptCompiler* compiler, const AbstractNodePtr &node)
{
    ObjectAbstractNode *obj = static_cast<ObjectAbstractNode*>(node.get());
    Pass* pass = any_cast<Pass*>(obj->parent->context);
    Technique* technique = pass->getParent();
    Material* material = technique->getParent();
    ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr();
    String dstTechniqueSchemeName = obj->name;
    bool techniqueCreated;

    // Make sure the scheme name is valid - use default if none exists.
    if (dstTechniqueSchemeName.empty())
        dstTechniqueSchemeName = ShaderGenerator::DEFAULT_SCHEME_NAME;

    // Create the shader based technique.
    techniqueCreated = shaderGenerator->createShaderBasedTechnique(technique,
        dstTechniqueSchemeName,
        shaderGenerator->getCreateShaderOverProgrammablePass());

    // Case technique successfully created.
    if (techniqueCreated)
    {
        // Go over all the render state properties.
        for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i)
        {
            if((*i)->type == ANT_PROPERTY)
            {
                PropertyAbstractNode *prop = static_cast<PropertyAbstractNode*>((*i).get());

                // Handle light count property.
                if (prop->name == "light_count")
                {
                    if (prop->values.size() != 3)
                    {
                        compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    }
                    else
                    {
                        std::vector<int> lightCount;
                        if (getVector(prop->values.begin(), prop->values.end(), lightCount, 3))
                        {
                            shaderGenerator->createScheme(dstTechniqueSchemeName);
                            RenderState* renderState = shaderGenerator->getRenderState(dstTechniqueSchemeName,
                                material->getName(), material->getGroup(), pass->getIndex());

                            renderState->setLightCount(Vector3i(lightCount.data()));
                            renderState->setLightCountAutoUpdate(false);
                        }
                        else
                        {
                            compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                        }
                    }
                }

                // Handle the rest of the custom properties.
                else
                {
                    SubRenderState* subRenderState = ShaderGenerator::getSingleton().createSubRenderState(compiler, prop, pass, this);
                    if (subRenderState)
                    {
                        addSubRenderState(subRenderState, dstTechniqueSchemeName, material->getName(), material->getGroup(), pass->getIndex());
                    }
                    else
                    {
                        compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, prop->name);
                    }
                }
            }
            else
            {
                processNode(compiler, *i);
            }
        }

        mGeneratedRenderState = NULL;
    }

}

//-----------------------------------------------------------------------------
void SGScriptTranslator::addSubRenderState(SubRenderState* newSubRenderState,
        const String& dstTechniqueSchemeName, const String& materialName, const String& groupName, unsigned short passIndex)
{
    assert(newSubRenderState);

    //check if a different sub render state of the same type already exists
    ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr();

    //create a new scheme if needed
    shaderGenerator->createScheme(dstTechniqueSchemeName);

    //update the active render state
    mGeneratedRenderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, materialName, groupName, passIndex);

    //add the new sub render state
    mGeneratedRenderState->addTemplateSubRenderState(newSubRenderState);
}

}
}
<|endoftext|>


<commit_before>/* dlvhex -- Answer-Set Programming with external interfaces.
 * Copyright (C) 2005, 2006, 2007 Roman Schindlauer
 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Thomas Krennwallner
 * Copyright (C) 2009, 2010 Peter Schüller
 *
 * This file is part of dlvhex.
 *
 * dlvhex is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * dlvhex is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with dlvhex; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 */

/**
 * @file BoostComponentFinder.cpp
 * @author Roman Schindlauer
 * @date Wed Jan 25 14:34:20 CET 2006
 *
 * @brief Strategy class for finding SCCs and WCCs from a given program graph, using
 * the Boost Graph Library.
 *
 *
 */

#include "dlvhex/BoostComponentFinder.h"
#include "dlvhex/globals.h"
#include "dlvhex/PrintVisitor.h"
#include "dlvhex/Component.h"

#include <sstream>

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>
#include <boost/graph/strong_components.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/algorithm/string/replace.hpp>

DLVHEX_NAMESPACE_BEGIN

void
BoostComponentFinder::makeEdges(const std::vector<AtomNodePtr>& nodes,
                                Edges& edges) const
{
    for (std::vector<AtomNodePtr>::const_iterator node = nodes.begin();
         node != nodes.end();
         ++node)
    {
        ComponentFinder::Vertex v1 = (*node)->getId();

        //
        // considering all types of dependencies
        //
        for (std::set<Dependency>::const_iterator d = (*node)->getSucceeding().begin();
            d != (*node)->getSucceeding().end();
            ++d)
        {
            ComponentFinder::Vertex v2 = (*d).getAtomNode()->getId();

            //
            // making edge from v2 to v1, because the direction is not relevant
            // for finding WCCs and SCCs and this is the "traditional" direction
            // for lp-dependency (head->body), and we want these arrows in the
            // graphviz output (see below)!
            //
            edges.push_back(ComponentFinder::Edge(v2, v1));
        }

    }
}

void
BoostComponentFinder::selectNodes(const Vertices& vertices,
                                  const std::vector<AtomNodePtr>& nodes,
                                  std::vector<AtomNodePtr>& newnodes) const
{
    newnodes.clear();

    for (ComponentFinder::Vertices::const_iterator vi = vertices.begin();
            vi != vertices.end();
            ++vi)
    {
        ///@todo this is too expensive - all the vertices-stuff should
        /// actually be done in boost, it could handle all these
        /// properties internally.  there shouldn't be any mapping and
        /// searching here!
        std::vector<AtomNodePtr>::const_iterator an;

        for (an = nodes.begin(); an != nodes.end(); ++an)
        {
            if ((*an)->getId() == *vi)
                break;
        }

        if (an != nodes.end())
        {
            newnodes.push_back(*an);
        }
    }
}

void
BoostComponentFinder::findWeakComponents(const std::vector<AtomNodePtr>& nodes,
                                         std::vector<std::vector<AtomNodePtr> >& wccs)
{
    /*
    std::map<int, Vertex> vmap;

    Edges contedges;

    for (Edges::const_iterator ei = edges.begin();
         ei != edges.end();
         ++ei)
    {

    }
    */

    ComponentFinder::Edges edges;

    makeEdges(nodes, edges);

    using namespace boost;
    {
        typedef adjacency_list <listS, vecS, undirectedS> Graph;

        Graph G;

        for (Edges::const_iterator ei = edges.begin();
             ei != edges.end();
             ++ei)
        {
            add_edge(ei->first, ei->second, G);
        }

        std::vector<int> component(num_vertices(G));

        int num = connected_components(G, &component[0]);

//        std::cout << "Total number of components: " << num << std::endl;

        std::vector<AtomNodePtr> wcc;

        for (int cn = 0; cn < num; ++cn)
        {
            Vertices thiscomponent;

            for (std::vector<int>::size_type i = 0; i != component.size(); ++i)
            {
                if (component[i] == cn)
                {
                    thiscomponent.push_back(Vertex(i));
                }
            }

            //
            // hack - remove all single noded-components, as long as we don't know
            // how to use boost with non-contiguous vertices!
            //
            if (thiscomponent.size() > 1)
            {
                //.push_back(thiscomponent);

                wcc.clear();

                selectNodes(thiscomponent, nodes, wcc);

                wccs.push_back(wcc);
            }
        }

//        for (std::vector<int>::size_type i = 0; i != component.size(); ++i)
//            std::cout << "Vertex " << i <<" is in component " << component[i] << std::endl;
//        std::cout << std::endl;

    }
}

void
BoostComponentFinder::findStrongComponents(const std::vector<AtomNodePtr>& nodes,
                                           std::vector<std::vector<AtomNodePtr> >& sccs)
{
    ComponentFinder::Edges edges;

    makeEdges(nodes, edges);

    using namespace boost;
    {
        typedef adjacency_list<vecS, vecS, directedS> Graph;

        Graph G(0);

        for (Edges::const_iterator ei = edges.begin();
             ei != edges.end();
             ++ei)
	  {
            add_edge(ei->first, ei->second, G);
	  }

        std::vector<int> component(num_vertices(G));

        int num = strong_components(G, &component[0]);
        //std::cout << "Total number of components: " << num << std::endl;

        std::vector<AtomNodePtr> scc;

        for (int cn = 0; cn < num; ++cn)
        {
            Vertices thiscomponent;

            for (std::vector<int>::size_type i = 0; i != component.size(); ++i)
            {
                if (component[i] == cn)
                    thiscomponent.push_back(Vertex(i));
            }

            /// @todo boost adds also single components as strong
            /// components. we avoid that for now (25-01-06), because
            /// having so many sccs will mean to call dlv a lot, which
            /// might cost a lot. better to put an effort into the
            /// graphprocessor strategy of finding big wccs on the
            /// fly.

            /// @todo try the other way by using a different
            /// boostcomponentfinder with a different graphprocessor!

            //
            // only add components with more than one vertex:
            //
            if (thiscomponent.size() > 1)
            {
                //components.push_back(thiscomponent);

                scc.clear();

                selectNodes(thiscomponent, nodes, scc);

                sccs.push_back(scc);
            }
        }

	if (Globals::Instance()->doVerbose(Globals::DUMP_DEPENDENCY_GRAPH))
	  {
	    //
	    // create a label table for the graphviz output
	    //
	    std::string nms[3 * nodes.size()];

	    std::ostringstream oss;
	    RawPrintVisitor rpv(oss);

	    for (unsigned y = 0; y < nodes.size(); ++y)
	      {
		oss.str("");

		nodes[y]->getAtom()->accept(rpv);

		std::string at(oss.str());

		boost::algorithm::replace_all(at, "\"", "\\\"");

		nms[y] = at;
	      }

	    std::ofstream out;

	    out.open(Globals::Instance()->lpfilename.c_str());
	    write_graphviz(out, G, make_label_writer(nms));
	    out.close();

	    Globals::Instance()->getVerboseStream() << "Graph written to "
						    << Globals::Instance()->lpfilename << std::endl;
	  }
    }
}

DLVHEX_NAMESPACE_END

// Local Variables:
// mode: C++
// End:
<commit_msg>applied nice part of clang fix (the one that does not deal with a clang bug)<commit_after>/* dlvhex -- Answer-Set Programming with external interfaces.
 * Copyright (C) 2005, 2006, 2007 Roman Schindlauer
 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Thomas Krennwallner
 * Copyright (C) 2009, 2010 Peter Schüller
 *
 * This file is part of dlvhex.
 *
 * dlvhex is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * dlvhex is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with dlvhex; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 */

/**
 * @file BoostComponentFinder.cpp
 * @author Roman Schindlauer
 * @date Wed Jan 25 14:34:20 CET 2006
 *
 * @brief Strategy class for finding SCCs and WCCs from a given program graph, using
 * the Boost Graph Library.
 *
 *
 */

#include "dlvhex/BoostComponentFinder.h"
#include "dlvhex/globals.h"
#include "dlvhex/PrintVisitor.h"
#include "dlvhex/Component.h"

#include <sstream>

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>
#include <boost/graph/strong_components.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/algorithm/string/replace.hpp>

DLVHEX_NAMESPACE_BEGIN

void
BoostComponentFinder::makeEdges(const std::vector<AtomNodePtr>& nodes,
                                Edges& edges) const
{
    for (std::vector<AtomNodePtr>::const_iterator node = nodes.begin();
         node != nodes.end();
         ++node)
    {
        ComponentFinder::Vertex v1 = (*node)->getId();

        //
        // considering all types of dependencies
        //
        for (std::set<Dependency>::const_iterator d = (*node)->getSucceeding().begin();
            d != (*node)->getSucceeding().end();
            ++d)
        {
            ComponentFinder::Vertex v2 = (*d).getAtomNode()->getId();

            //
            // making edge from v2 to v1, because the direction is not relevant
            // for finding WCCs and SCCs and this is the "traditional" direction
            // for lp-dependency (head->body), and we want these arrows in the
            // graphviz output (see below)!
            //
            edges.push_back(ComponentFinder::Edge(v2, v1));
        }

    }
}

void
BoostComponentFinder::selectNodes(const Vertices& vertices,
                                  const std::vector<AtomNodePtr>& nodes,
                                  std::vector<AtomNodePtr>& newnodes) const
{
    newnodes.clear();

    for (ComponentFinder::Vertices::const_iterator vi = vertices.begin();
            vi != vertices.end();
            ++vi)
    {
        ///@todo this is too expensive - all the vertices-stuff should
        /// actually be done in boost, it could handle all these
        /// properties internally.  there shouldn't be any mapping and
        /// searching here!
        std::vector<AtomNodePtr>::const_iterator an;

        for (an = nodes.begin(); an != nodes.end(); ++an)
        {
            if ((*an)->getId() == *vi)
                break;
        }

        if (an != nodes.end())
        {
            newnodes.push_back(*an);
        }
    }
}

void
BoostComponentFinder::findWeakComponents(const std::vector<AtomNodePtr>& nodes,
                                         std::vector<std::vector<AtomNodePtr> >& wccs)
{
    /*
    std::map<int, Vertex> vmap;

    Edges contedges;

    for (Edges::const_iterator ei = edges.begin();
         ei != edges.end();
         ++ei)
    {

    }
    */

    ComponentFinder::Edges edges;

    makeEdges(nodes, edges);

    using namespace boost;
    {
        typedef adjacency_list <listS, vecS, undirectedS> Graph;

        Graph G;

        for (Edges::const_iterator ei = edges.begin();
             ei != edges.end();
             ++ei)
        {
            add_edge(ei->first, ei->second, G);
        }

        std::vector<int> component(num_vertices(G));

        int num = connected_components(G, &component[0]);

//        std::cout << "Total number of components: " << num << std::endl;

        std::vector<AtomNodePtr> wcc;

        for (int cn = 0; cn < num; ++cn)
        {
            Vertices thiscomponent;

            for (std::vector<int>::size_type i = 0; i != component.size(); ++i)
            {
                if (component[i] == cn)
                {
                    thiscomponent.push_back(Vertex(i));
                }
            }

            //
            // hack - remove all single noded-components, as long as we don't know
            // how to use boost with non-contiguous vertices!
            //
            if (thiscomponent.size() > 1)
            {
                //.push_back(thiscomponent);

                wcc.clear();

                selectNodes(thiscomponent, nodes, wcc);

                wccs.push_back(wcc);
            }
        }

//        for (std::vector<int>::size_type i = 0; i != component.size(); ++i)
//            std::cout << "Vertex " << i <<" is in component " << component[i] << std::endl;
//        std::cout << std::endl;

    }
}

void
BoostComponentFinder::findStrongComponents(const std::vector<AtomNodePtr>& nodes,
                                           std::vector<std::vector<AtomNodePtr> >& sccs)
{
    ComponentFinder::Edges edges;

    makeEdges(nodes, edges);

    using namespace boost;
    {
        typedef adjacency_list<vecS, vecS, directedS> Graph;

        Graph G(0);

        for (Edges::const_iterator ei = edges.begin();
             ei != edges.end();
             ++ei)
	  {
            add_edge(ei->first, ei->second, G);
	  }

        std::vector<int> component(num_vertices(G));

        int num = strong_components(G, &component[0]);
        //std::cout << "Total number of components: " << num << std::endl;

        std::vector<AtomNodePtr> scc;

        for (int cn = 0; cn < num; ++cn)
        {
            Vertices thiscomponent;

            for (std::vector<int>::size_type i = 0; i != component.size(); ++i)
            {
                if (component[i] == cn)
                    thiscomponent.push_back(Vertex(i));
            }

            /// @todo boost adds also single components as strong
            /// components. we avoid that for now (25-01-06), because
            /// having so many sccs will mean to call dlv a lot, which
            /// might cost a lot. better to put an effort into the
            /// graphprocessor strategy of finding big wccs on the
            /// fly.

            /// @todo try the other way by using a different
            /// boostcomponentfinder with a different graphprocessor!

            //
            // only add components with more than one vertex:
            //
            if (thiscomponent.size() > 1)
            {
                //components.push_back(thiscomponent);

                scc.clear();

                selectNodes(thiscomponent, nodes, scc);

                sccs.push_back(scc);
            }
        }

	if (Globals::Instance()->doVerbose(Globals::DUMP_DEPENDENCY_GRAPH))
	  {
	    //
	    // create a label table for the graphviz output
	    //
	    const int nnames = 3*nodes.size();
	    std::vector<std::string> nms(nnames);
	    const char* nmsc[nnames];

	    std::ostringstream oss;
	    RawPrintVisitor rpv(oss);

	    for (unsigned y = 0; y < nodes.size(); ++y)
	      {
		oss.str("");

		nodes[y]->getAtom()->accept(rpv);

		std::string at(oss.str());

		boost::algorithm::replace_all(at, "\"", "\\\"");

		nms[y] = at;
		nmsc[y] = nms[y].c_str();
	      }

	    std::ofstream out;

	    out.open(Globals::Instance()->lpfilename.c_str());
	    write_graphviz(out, G, make_label_writer(nmsc));
	    out.close();

	    Globals::Instance()->getVerboseStream() << "Graph written to "
						    << Globals::Instance()->lpfilename << std::endl;
	  }
    }
}

DLVHEX_NAMESPACE_END

// Local Variables:
// mode: C++
// End:
<|endoftext|>


<commit_before>#pragma once

#include <Physic/Utils/BtConversion.hpp>
#include <Systems/System.h>
#include <Components/RigidBody.hpp>
#include <Physic/BulletDynamicManager.hpp>
#include <Core/Engine.hh>
#include <Entities/EntityFlags.hh>

#include <future>

namespace AGE
{
	class BulletDynamicSystem : public System
	{
	public:
		BulletDynamicSystem(AScene *scene)
			: System(std::move(scene))
			, _manager(nullptr)
			, _filter(std::move(scene))
		{
			_name = "bullet_dynamic_system";
			_manager = dynamic_cast<BulletDynamicManager*>(_scene->getInstance<BulletCollisionManager>());
			_filter.requireComponent<RigidBody>();
		}
		virtual ~BulletDynamicSystem(){}
	private:
		BulletDynamicManager* _manager;
		EntityFilter _filter;

		virtual void updateBegin(float time)
		{
			auto scene = _scene;
			for (auto e : _filter.getCollection())
			{
				if (e.getLink().isUserModified())
				{
					auto rb = e.getComponent<RigidBody>();
					if (rb->getMass() == 0)
					{
						rb->setTransformation(&e.getLink());
						e.getLink().setUserModified(false);
					}
				}

			}
			_manager->getWorld()->stepSimulation(static_cast<btScalar>(time), 10);
		}

		virtual void updateEnd(float time)
		{}

		virtual void mainUpdate(float time)
		{
		}

		virtual bool initialize()
		{
			return true;
		}
	};
}<commit_msg>Physics deactivated when Dt == 0<commit_after>#pragma once

#include <Physic/Utils/BtConversion.hpp>
#include <Systems/System.h>
#include <Components/RigidBody.hpp>
#include <Physic/BulletDynamicManager.hpp>
#include <Core/Engine.hh>
#include <Entities/EntityFlags.hh>

#include <future>

namespace AGE
{
	class BulletDynamicSystem : public System
	{
	public:
		BulletDynamicSystem(AScene *scene)
			: System(std::move(scene))
			, _manager(nullptr)
			, _filter(std::move(scene))
		{
			_name = "bullet_dynamic_system";
			_manager = dynamic_cast<BulletDynamicManager*>(_scene->getInstance<BulletCollisionManager>());
			_filter.requireComponent<RigidBody>();
		}
		virtual ~BulletDynamicSystem(){}
	private:
		BulletDynamicManager* _manager;
		EntityFilter _filter;

		virtual void updateBegin(float time)
		{
			auto scene = _scene;
			for (auto e : _filter.getCollection())
			{
				if (e.getLink().isUserModified())
				{
					auto rb = e.getComponent<RigidBody>();
					if (rb->getMass() == 0)
					{
						rb->setTransformation(&e.getLink());
						e.getLink().setUserModified(false);
					}
				}

			}
			if (time == 0.0f)
			{
				return;
			}
			_manager->getWorld()->stepSimulation(static_cast<btScalar>(time), 10);
		}

		virtual void updateEnd(float time)
		{}

		virtual void mainUpdate(float time)
		{
		}

		virtual bool initialize()
		{
			return true;
		}
	};
}<|endoftext|>


<commit_before>/* -*-  mode: c++; c-default-style: "google"; indent-tabs-mode: nil -*- */

/*
  This WRM evaluator evaluates saturation of gas, liquid, and ice from
  capillary pressures for the ice-liquid and liquid-gas pairs.

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

#include "wrm_permafrost_evaluator.hh"
#include "wrm_partition.hh"

namespace Amanzi {
namespace Flow {
namespace FlowRelations {

/* --------------------------------------------------------------------------------
  Constructor from just a ParameterList, reads WRMs and permafrost models from list.
 -------------------------------------------------------------------------------- */
WRMPermafrostEvaluator::WRMPermafrostEvaluator(Teuchos::ParameterList& plist) :
    SecondaryVariablesFieldEvaluator(plist) {

  // get the WRMs
  ASSERT(plist_.isSublist("WRM parameters"));
  Teuchos::ParameterList wrm_plist = plist_.sublist("WRM parameters");
  wrms_ = createWRMPartition(wrm_plist);

  // and the permafrost models
  ASSERT(plist_.isSublist("permafrost model parameters"));
  Teuchos::ParameterList perm_plist = plist_.sublist("permafrost model parameters");
  permafrost_models_ = createWRMPermafrostModelPartition(perm_plist, wrms_);

  InitializeFromPlist_();
}

/* --------------------------------------------------------------------------------
  Constructor with WRMs.
 -------------------------------------------------------------------------------- */
WRMPermafrostEvaluator::WRMPermafrostEvaluator(Teuchos::ParameterList& plist,
        const Teuchos::RCP<WRMPartition>& wrms) :
    SecondaryVariablesFieldEvaluator(plist),
    wrms_(wrms) {

  // and the permafrost models
  ASSERT(plist_.isSublist("permafrost model parameters"));
  Teuchos::ParameterList perm_plist = plist_.sublist("permafrost model parameters");
  permafrost_models_ = createWRMPermafrostModelPartition(perm_plist, wrms_);

  InitializeFromPlist_();
}

/* --------------------------------------------------------------------------------
  Constructor with Permafrost models.
 -------------------------------------------------------------------------------- */
WRMPermafrostEvaluator::WRMPermafrostEvaluator(Teuchos::ParameterList& plist,
        const Teuchos::RCP<WRMPermafrostModelPartition>& models) :
    SecondaryVariablesFieldEvaluator(plist),
    permafrost_models_(models) {

  InitializeFromPlist_();
}

/* --------------------------------------------------------------------------------
  Copy constructor
 -------------------------------------------------------------------------------- */
WRMPermafrostEvaluator::WRMPermafrostEvaluator(const WRMPermafrostEvaluator& other) :
    SecondaryVariablesFieldEvaluator(other),
    pc_liq_key_(other.pc_liq_key_),
    pc_ice_key_(other.pc_ice_key_),
    s_l_key_(other.s_l_key_),
    permafrost_models_(other.permafrost_models_) {}

/* --------------------------------------------------------------------------------
  Virtual opy constructor as a FieldEvaluator.
 -------------------------------------------------------------------------------- */
Teuchos::RCP<FieldEvaluator>
WRMPermafrostEvaluator::Clone() const {
  return Teuchos::rcp(new WRMPermafrostEvaluator(*this));
}

/* --------------------------------------------------------------------------------
  Initialization of keys.
 -------------------------------------------------------------------------------- */
void WRMPermafrostEvaluator::InitializeFromPlist_() {
  // my keys are for saturation -- order matters... gas -> liq -> ice
  my_keys_.push_back(plist_.get<string>("gas saturation key", "saturation_gas"));
  s_l_key_ = plist_.get<string>("liquid saturation key", "saturation_liquid");
  my_keys_.push_back(s_l_key_);
  my_keys_.push_back(plist_.get<string>("ice saturation key", "saturation_ice"));

  // liquid-gas capillary pressure
  pc_liq_key_ = plist_.get<string>("gas-liquid capillary pressure key",
          "capillary_pressure_gas_liq");
  dependencies_.insert(pc_liq_key_);

  // liquid-gas capillary pressure
  pc_ice_key_ = plist_.get<string>("liquid-ice capillary pressure key",
          "capillary_pressure_liq_ice");
  dependencies_.insert(pc_ice_key_);
}

void WRMPermafrostEvaluator::EvaluateField_(const Teuchos::Ptr<State>& S,
        const std::vector<Teuchos::Ptr<CompositeVector> >& results) {
  // Initialize the MeshPartition
  if (!permafrost_models_->first->initialized())
    permafrost_models_->first->Initialize(results[0]->Mesh());

  // Cell values
  Epetra_MultiVector& satg_c = *results[0]->ViewComponent("cell",false);
  Epetra_MultiVector& satl_c = *results[1]->ViewComponent("cell",false);
  Epetra_MultiVector& sati_c = *results[2]->ViewComponent("cell",false);

  const Epetra_MultiVector& pc_liq_c = *S->GetFieldData(pc_liq_key_)
      ->ViewComponent("cell",false);
  const Epetra_MultiVector& pc_ice_c = *S->GetFieldData(pc_ice_key_)
      ->ViewComponent("cell",false);

  double sats[3];
  int ncells = satg_c.MyLength();
  for (AmanziMesh::Entity_ID c=0; c!=ncells; ++c) {
    int i = (*permafrost_models_->first)[c];
    permafrost_models_->second[i]->saturations(pc_liq_c[0][c], pc_ice_c[0][c], sats);
    satg_c[0][c] = sats[0];
    satl_c[0][c] = sats[1];
    sati_c[0][c] = sats[2];
  }

  // Potentially do face values as well, though only for saturation_liquid?
  if (results[0]->HasComponent("boundary_face")) {
    Epetra_MultiVector& satg_bf = *results[0]->ViewComponent("boundary_face",false);
    Epetra_MultiVector& satl_bf = *results[1]->ViewComponent("boundary_face",false);
    Epetra_MultiVector& sati_bf = *results[2]->ViewComponent("boundary_face",false);
    const Epetra_MultiVector& pc_liq_bf = *S->GetFieldData(pc_liq_key_)
        ->ViewComponent("boundary_face",false);
    const Epetra_MultiVector& pc_ice_bf = *S->GetFieldData(pc_ice_key_)
        ->ViewComponent("boundary_face",false);

    // Need to get boundary face's inner cell to specify the WRM.
    Teuchos::RCP<const AmanziMesh::Mesh> mesh = results[0]->Mesh();
    const Epetra_Map& vandelay_map = mesh->exterior_face_epetra_map();
    const Epetra_Map& face_map = mesh->face_epetra_map(false);
    AmanziMesh::Entity_ID_List cells;

    // calculate boundary face values
    int nbfaces = satg_bf.MyLength();
    for (int bf=0; bf!=nbfaces; ++bf) {
      // given a boundary face, we need the internal cell to choose the right WRM
      AmanziMesh::Entity_ID f = face_map.LID(vandelay_map.GID(bf));
      mesh->face_get_cells(f, AmanziMesh::USED, &cells);
      ASSERT(cells.size() == 1);

      int i = (*permafrost_models_->first)[cells[0]];
      permafrost_models_->second[i]
          ->saturations(pc_liq_bf[0][bf], pc_ice_bf[0][bf], sats);
      satg_bf[0][bf] = sats[0];
      satl_bf[0][bf] = sats[1];
      sati_bf[0][bf] = sats[2];
    }
  }
}

void
WRMPermafrostEvaluator::EvaluateFieldPartialDerivative_(const Teuchos::Ptr<State>& S,
        Key wrt_key, const std::vector<Teuchos::Ptr<CompositeVector> > & results) {

  // Cell values
  Epetra_MultiVector& satg_c = *results[0]->ViewComponent("cell",false);
  Epetra_MultiVector& satl_c = *results[1]->ViewComponent("cell",false);
  Epetra_MultiVector& sati_c = *results[2]->ViewComponent("cell",false);

  const Epetra_MultiVector& pc_liq_c = *S->GetFieldData(pc_liq_key_)
      ->ViewComponent("cell",false);
  const Epetra_MultiVector& pc_ice_c = *S->GetFieldData(pc_ice_key_)
      ->ViewComponent("cell",false);

  double dsats[3];
  if (wrt_key == pc_liq_key_) {
    int ncells = satg_c.MyLength();
    for (AmanziMesh::Entity_ID c=0; c!=ncells; ++c) {
      int i = (*permafrost_models_->first)[c];
      permafrost_models_->second[i]->dsaturations_dpc_liq(
          pc_liq_c[0][c], pc_ice_c[0][c], dsats);

      satg_c[0][c] = dsats[0];
      satl_c[0][c] = dsats[1];
      sati_c[0][c] = dsats[2];
    }

  } else if (wrt_key == pc_ice_key_) {
    int ncells = satg_c.MyLength();
    for (AmanziMesh::Entity_ID c=0; c!=ncells; ++c) {
      int i = (*permafrost_models_->first)[c];
      permafrost_models_->second[i]->dsaturations_dpc_ice(
          pc_liq_c[0][c], pc_ice_c[0][c], dsats);

      satg_c[0][c] = dsats[0];
      satl_c[0][c] = dsats[1];
      sati_c[0][c] = dsats[2];
    }
  } else {
    ASSERT(0);
  }

  // Potentially do face values as well, though only for saturation_liquid?
  if (results[1]->HasComponent("boundary_face")) {
    ASSERT(!results[0]->HasComponent("boundary_face"));
    ASSERT(!results[2]->HasComponent("boundary_face"));

    Epetra_MultiVector& sat_bf = *results[1]->ViewComponent("boundary_face",false);
    const Epetra_MultiVector& pc_liq_bf = *S->GetFieldData(pc_liq_key_)
        ->ViewComponent("boundary_face",false);
    const Epetra_MultiVector& pc_ice_bf = *S->GetFieldData(pc_ice_key_)
        ->ViewComponent("boundary_face",false);

    // Need to get boundary face's inner cell to specify the WRM.
    Teuchos::RCP<const AmanziMesh::Mesh> mesh = results[0]->Mesh();
    const Epetra_Map& face_map = mesh->face_epetra_map(false);
    const Epetra_Map& vandelay_map = mesh->exterior_face_epetra_map();
    AmanziMesh::Entity_ID_List cells;

    if (wrt_key == pc_liq_key_) {
      // calculate boundary face values
      int nbfaces = sat_bf.MyLength();
      for (int bf=0; bf!=nbfaces; ++bf) {
        // given a boundary face, we need the internal cell to choose the right WRM
        AmanziMesh::Entity_ID f = face_map.LID(vandelay_map.GID(bf));
        mesh->face_get_cells(f, AmanziMesh::USED, &cells);
        ASSERT(cells.size() == 1);

        int i = (*permafrost_models_->first)[cells[0]];
        permafrost_models_->second[i]->dsaturations_dpc_liq(
            pc_liq_bf[0][bf], pc_ice_bf[0][bf], dsats);
        sat_bf[0][bf] = dsats[1];
      }

    } else if (wrt_key == pc_ice_key_) {
      // calculate boundary face values
      int nbfaces = sat_bf.MyLength();
      for (int bf=0; bf!=nbfaces; ++bf) {
        // given a boundary face, we need the internal cell to choose the right WRM
        AmanziMesh::Entity_ID f = face_map.LID(vandelay_map.GID(bf));
        mesh->face_get_cells(f, AmanziMesh::USED, &cells);
        ASSERT(cells.size() == 1);

        int i = (*permafrost_models_->first)[cells[0]];
        permafrost_models_->second[i]->dsaturations_dpc_ice(
            pc_liq_bf[0][bf], pc_ice_bf[0][bf], dsats);
        sat_bf[0][bf] = dsats[1];
      }
    } else {
      ASSERT(0);
    }
  }
}

} // namespace
} // namespace
} // namespace

<commit_msg>megering stuff<commit_after>/* -*-  mode: c++; c-default-style: "google"; indent-tabs-mode: nil -*- */

/*
  This WRM evaluator evaluates saturation of gas, liquid, and ice from
  capillary pressures for the ice-liquid and liquid-gas pairs.

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

#include "wrm_permafrost_evaluator.hh"
#include "wrm_partition.hh"

namespace Amanzi {
namespace Flow {
namespace FlowRelations {

/* --------------------------------------------------------------------------------
  Constructor from just a ParameterList, reads WRMs and permafrost models from list.
 -------------------------------------------------------------------------------- */
WRMPermafrostEvaluator::WRMPermafrostEvaluator(Teuchos::ParameterList& plist) :
    SecondaryVariablesFieldEvaluator(plist) {

  // get the WRMs
  ASSERT(plist_.isSublist("WRM parameters"));
  Teuchos::ParameterList wrm_plist = plist_.sublist("WRM parameters");
  wrms_ = createWRMPartition(wrm_plist);

  // and the permafrost models
  ASSERT(plist_.isSublist("permafrost model parameters"));
  Teuchos::ParameterList perm_plist = plist_.sublist("permafrost model parameters");
  permafrost_models_ = createWRMPermafrostModelPartition(perm_plist, wrms_);

  InitializeFromPlist_();
}

/* --------------------------------------------------------------------------------
  Constructor with WRMs.
 -------------------------------------------------------------------------------- */
WRMPermafrostEvaluator::WRMPermafrostEvaluator(Teuchos::ParameterList& plist,
        const Teuchos::RCP<WRMPartition>& wrms) :
    SecondaryVariablesFieldEvaluator(plist),
    wrms_(wrms) {

  // and the permafrost models
  ASSERT(plist_.isSublist("permafrost model parameters"));
  Teuchos::ParameterList perm_plist = plist_.sublist("permafrost model parameters");
  permafrost_models_ = createWRMPermafrostModelPartition(perm_plist, wrms_);

  InitializeFromPlist_();
}

/* --------------------------------------------------------------------------------
  Constructor with Permafrost models.
 -------------------------------------------------------------------------------- */
WRMPermafrostEvaluator::WRMPermafrostEvaluator(Teuchos::ParameterList& plist,
        const Teuchos::RCP<WRMPermafrostModelPartition>& models) :
    SecondaryVariablesFieldEvaluator(plist),
    permafrost_models_(models) {

  InitializeFromPlist_();
}

/* --------------------------------------------------------------------------------
  Copy constructor
 -------------------------------------------------------------------------------- */
WRMPermafrostEvaluator::WRMPermafrostEvaluator(const WRMPermafrostEvaluator& other) :
    SecondaryVariablesFieldEvaluator(other),
    pc_liq_key_(other.pc_liq_key_),
    pc_ice_key_(other.pc_ice_key_),
    s_l_key_(other.s_l_key_),
    permafrost_models_(other.permafrost_models_) {}

/* --------------------------------------------------------------------------------
  Virtual opy constructor as a FieldEvaluator.
 -------------------------------------------------------------------------------- */
Teuchos::RCP<FieldEvaluator>
WRMPermafrostEvaluator::Clone() const {
  return Teuchos::rcp(new WRMPermafrostEvaluator(*this));
}

/* --------------------------------------------------------------------------------
  Initialization of keys.
 -------------------------------------------------------------------------------- */
void WRMPermafrostEvaluator::InitializeFromPlist_() {
  // my keys are for saturation -- order matters... gas -> liq -> ice
  my_keys_.push_back(plist_.get<string>("gas saturation key", "saturation_gas"));
  s_l_key_ = plist_.get<string>("liquid saturation key", "saturation_liquid");
  my_keys_.push_back(s_l_key_);
  my_keys_.push_back(plist_.get<string>("ice saturation key", "saturation_ice"));

  // liquid-gas capillary pressure
  pc_liq_key_ = plist_.get<string>("gas-liquid capillary pressure key",
          "capillary_pressure_gas_liq");
  dependencies_.insert(pc_liq_key_);

  // liquid-gas capillary pressure
  pc_ice_key_ = plist_.get<string>("liquid-ice capillary pressure key",
          "capillary_pressure_liq_ice");
  dependencies_.insert(pc_ice_key_);
}

void WRMPermafrostEvaluator::EvaluateField_(const Teuchos::Ptr<State>& S,
        const std::vector<Teuchos::Ptr<CompositeVector> >& results) {
  // Initialize the MeshPartition
  if (!permafrost_models_->first->initialized())
    permafrost_models_->first->Initialize(results[0]->Mesh());

  // Cell values
  Epetra_MultiVector& satg_c = *results[0]->ViewComponent("cell",false);
  Epetra_MultiVector& satl_c = *results[1]->ViewComponent("cell",false);
  Epetra_MultiVector& sati_c = *results[2]->ViewComponent("cell",false);

  const Epetra_MultiVector& pc_liq_c = *S->GetFieldData(pc_liq_key_)
      ->ViewComponent("cell",false);
  const Epetra_MultiVector& pc_ice_c = *S->GetFieldData(pc_ice_key_)
      ->ViewComponent("cell",false);

  double sats[3];
  int ncells = satg_c.MyLength();
  for (AmanziMesh::Entity_ID c=0; c!=ncells; ++c) {
    int i = (*permafrost_models_->first)[c];
    permafrost_models_->second[i]->saturations(pc_liq_c[0][c], pc_ice_c[0][c], sats);
    satg_c[0][c] = sats[0];
    satl_c[0][c] = sats[1];
    sati_c[0][c] = sats[2];
  }

  // Potentially do face values as well, though only for saturation_liquid?
  if (results[0]->HasComponent("boundary_face")) {
    Epetra_MultiVector& satg_bf = *results[0]->ViewComponent("boundary_face",false);
    Epetra_MultiVector& satl_bf = *results[1]->ViewComponent("boundary_face",false);
    Epetra_MultiVector& sati_bf = *results[2]->ViewComponent("boundary_face",false);
    const Epetra_MultiVector& pc_liq_bf = *S->GetFieldData(pc_liq_key_)
        ->ViewComponent("boundary_face",false);
    const Epetra_MultiVector& pc_ice_bf = *S->GetFieldData(pc_ice_key_)
        ->ViewComponent("boundary_face",false);

    // Need to get boundary face's inner cell to specify the WRM.
    Teuchos::RCP<const AmanziMesh::Mesh> mesh = results[0]->Mesh();
    const Epetra_Map& vandelay_map = mesh->exterior_face_epetra_map();
    const Epetra_Map& face_map = mesh->face_epetra_map(false);
    AmanziMesh::Entity_ID_List cells;

    // calculate boundary face values
    int nbfaces = satg_bf.MyLength();
    for (int bf=0; bf!=nbfaces; ++bf) {
      // given a boundary face, we need the internal cell to choose the right WRM
      AmanziMesh::Entity_ID f = face_map.LID(vandelay_map.GID(bf));
      mesh->face_get_cells(f, AmanziMesh::USED, &cells);
      ASSERT(cells.size() == 1);

      int i = (*permafrost_models_->first)[cells[0]];
      permafrost_models_->second[i]
          ->saturations(pc_liq_bf[0][bf], pc_ice_bf[0][bf], sats);
      satg_bf[0][bf] = sats[0];
      satl_bf[0][bf] = sats[1];
      sati_bf[0][bf] = sats[2];
    }
  }
}

void
WRMPermafrostEvaluator::EvaluateFieldPartialDerivative_(const Teuchos::Ptr<State>& S,
        Key wrt_key, const std::vector<Teuchos::Ptr<CompositeVector> > & results) {

  // Cell values
  Epetra_MultiVector& satg_c = *results[0]->ViewComponent("cell",false);
  Epetra_MultiVector& satl_c = *results[1]->ViewComponent("cell",false);
  Epetra_MultiVector& sati_c = *results[2]->ViewComponent("cell",false);

  const Epetra_MultiVector& pc_liq_c = *S->GetFieldData(pc_liq_key_)
      ->ViewComponent("cell",false);
  const Epetra_MultiVector& pc_ice_c = *S->GetFieldData(pc_ice_key_)
      ->ViewComponent("cell",false);

  double dsats[3];
  if (wrt_key == pc_liq_key_) {
    int ncells = satg_c.MyLength();
    for (AmanziMesh::Entity_ID c=0; c!=ncells; ++c) {
      int i = (*permafrost_models_->first)[c];
      permafrost_models_->second[i]->dsaturations_dpc_liq(
          pc_liq_c[0][c], pc_ice_c[0][c], dsats);

      satg_c[0][c] = dsats[0];
      satl_c[0][c] = dsats[1];
      sati_c[0][c] = dsats[2];
    }

  } else if (wrt_key == pc_ice_key_) {
    int ncells = satg_c.MyLength();
    for (AmanziMesh::Entity_ID c=0; c!=ncells; ++c) {
      int i = (*permafrost_models_->first)[c];
      permafrost_models_->second[i]->dsaturations_dpc_ice(
          pc_liq_c[0][c], pc_ice_c[0][c], dsats);

      satg_c[0][c] = dsats[0];
      satl_c[0][c] = dsats[1];
      sati_c[0][c] = dsats[2];
    }
  } else {
    ASSERT(0);
  }

  // Potentially do face values as well, though only for saturation_liquid?
  if (results[0]->HasComponent("boundary_face")) {
    Epetra_MultiVector& satg_bf = *results[0]->ViewComponent("boundary_face",false);
    Epetra_MultiVector& satl_bf = *results[1]->ViewComponent("boundary_face",false);
    Epetra_MultiVector& sati_bf = *results[2]->ViewComponent("boundary_face",false);
    const Epetra_MultiVector& pc_liq_bf = *S->GetFieldData(pc_liq_key_)
        ->ViewComponent("boundary_face",false);
    const Epetra_MultiVector& pc_ice_bf = *S->GetFieldData(pc_ice_key_)
        ->ViewComponent("boundary_face",false);

    // Need to get boundary face's inner cell to specify the WRM.
    Teuchos::RCP<const AmanziMesh::Mesh> mesh = results[0]->Mesh();
    const Epetra_Map& face_map = mesh->face_epetra_map(false);
    const Epetra_Map& vandelay_map = mesh->exterior_face_epetra_map();
    AmanziMesh::Entity_ID_List cells;

    if (wrt_key == pc_liq_key_) {
      // calculate boundary face values
      int nbfaces = satl_bf.MyLength();
      for (int bf=0; bf!=nbfaces; ++bf) {
        // given a boundary face, we need the internal cell to choose the right WRM
        AmanziMesh::Entity_ID f = face_map.LID(vandelay_map.GID(bf));
        mesh->face_get_cells(f, AmanziMesh::USED, &cells);
        ASSERT(cells.size() == 1);

        int i = (*permafrost_models_->first)[cells[0]];
        permafrost_models_->second[i]->dsaturations_dpc_liq(
            pc_liq_bf[0][bf], pc_ice_bf[0][bf], dsats);
        satg_bf[0][bf] = dsats[0];
        satl_bf[0][bf] = dsats[1];
        sati_bf[0][bf] = dsats[2];
      }

    } else if (wrt_key == pc_ice_key_) {
      // calculate boundary face values
      int nbfaces = satl_bf.MyLength();
      for (int bf=0; bf!=nbfaces; ++bf) {
        // given a boundary face, we need the internal cell to choose the right WRM
        AmanziMesh::Entity_ID f = face_map.LID(vandelay_map.GID(bf));
        mesh->face_get_cells(f, AmanziMesh::USED, &cells);
        ASSERT(cells.size() == 1);

        int i = (*permafrost_models_->first)[cells[0]];
        permafrost_models_->second[i]->dsaturations_dpc_ice(
            pc_liq_bf[0][bf], pc_ice_bf[0][bf], dsats);
        satg_bf[0][bf] = dsats[0];
        satl_bf[0][bf] = dsats[1];
        sati_bf[0][bf] = dsats[2];
      }
    } else {
      ASSERT(0);
    }
  }
}

} // namespace
} // namespace
} // namespace

<|endoftext|>


<commit_before>#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <irrlicht/Keycodes.h>
#include <stdio.h>
#include <unistd.h>

#define RETURN 13
#define BS 8
#define SPACE 32

XKeyEvent createKeyEvent(Display *display,
                         Window &win,
                         Window &winRoot,
                         bool press,
                         int keycode,
                         int modifiers)
{
  // Largely lifted from
  // http://www.doctort.org/adam/nerd-notes/x11-fake-keypress-event.html
  XKeyEvent event;
  event.display = display;
  event.window = win;
  event.root = winRoot;
  event.subwindow = None;
  event.time = CurrentTime;
  event.x = 1;
  event.y = 1;
  event.x_root = 1;
  event.y_root = 1;
  event.same_screen = True;
  event.keycode = XKeysymToKeycode(display, keycode);
  event.state = modifiers;

  if(press)
    event.type = KeyPress;
  else
    event.type = KeyRelease;

  return event;
}

class X11Display {
  public:
    Display *display;
    Window winRoot;
    X11Display(const char* dispName);
    ~X11Display();
    int sendKeyEvent(int keycode, bool keyDown, int mod);
};

// TODO: fail out if display doesn't initialize
X11Display::X11Display(const char* dispName)
{
  display = XOpenDisplay(dispName);
  if(NULL == display) {
    printf("invalid X11 display: %s\n", dispName);
    throw;
  }
  winRoot = XDefaultRootWindow(display);
}

X11Display::~X11Display() { XCloseDisplay(display); }

int X11Display::sendKeyEvent(int keycode, bool keyDown, int mod = 0)
{
  if(-1==keycode)
    return 0;
  Window winFocus;
  int revert;

  XGetInputFocus(display, &winFocus, &revert);
  XKeyEvent event = createKeyEvent(display, winFocus, winRoot, keyDown, keycode, mod);
  XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent*)&event);
  return 0;
}

bool IsModKey(int keycode) {
  switch(keycode){
    //shift, control and menu (both left and right) are consecutive
    case irr::KEY_LSHIFT ... irr::KEY_RMENU :
      return true;
    default :
      return false;
  }
}

int mapKeyCode(int irrcode){
  switch(irrcode){
    //FIXME: only to get rid of arrow spam
    case 37 ... 40:
      return -1;
    case irr::KEY_BACK :
      return XK_BackSpace;
    case irr::KEY_TAB :
      return XK_Tab;
    //FIXME: Should escape be a modifier too?
    case irr::KEY_ESCAPE :
      return XK_Escape;
    case irr::KEY_RETURN :
      return XK_Return;
    case irr::KEY_MINUS :
      return XK_minus;
    case irr::KEY_PLUS :
      return XK_equal;
    case irr::KEY_OEM_1 :
      return XK_semicolon;
    case irr::KEY_OEM_2 :
      return XK_slash;
    case irr::KEY_OEM_4 :
      return XK_bracketleft;
    case irr::KEY_OEM_6 :
      return XK_bracketright;
    case irr::KEY_OEM_7 :
      return XK_apostrophe;
    case irr::KEY_PERIOD :
      return XK_period;
    case irr::KEY_COMMA :
      return XK_comma;
    case irr::KEY_OEM_5 :
      return XK_backslash;
    case irr::KEY_LSHIFT :
      return XK_Shift_L;
    case irr::KEY_RSHIFT :
      return XK_Shift_R;
    case irr::KEY_LCONTROL :
      return XK_Control_L;
    case irr::KEY_RCONTROL :
      return XK_Control_R;
    default:
      return irrcode;
  }
}

<commit_msg>Lined up prototypes for moving in to header file<commit_after>#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <irrlicht/Keycodes.h>
#include <stdio.h>
#include <unistd.h>

#define RETURN 13
#define BS 8
#define SPACE 32

XKeyEvent createKeyEvent(Display *display,
                         Window &win,
                         Window &winRoot,
                         bool press,
                         int keycode,
                         int modifiers);

class X11Display {
  public:
    Display *display;
    Window winRoot;
    X11Display(const char* dispName);
    ~X11Display();
    int sendKeyEvent(int keycode, bool keyDown, int mod);
};

bool IsModKey(int keycode);

int mapKeyCode(int irrcode);

XKeyEvent createKeyEvent(Display *display,
                         Window &win,
                         Window &winRoot,
                         bool press,
                         int keycode,
                         int modifiers)
{
  // Largely lifted from
  // http://www.doctort.org/adam/nerd-notes/x11-fake-keypress-event.html
  XKeyEvent event;
  event.display = display;
  event.window = win;
  event.root = winRoot;
  event.subwindow = None;
  event.time = CurrentTime;
  event.x = 1;
  event.y = 1;
  event.x_root = 1;
  event.y_root = 1;
  event.same_screen = True;
  event.keycode = XKeysymToKeycode(display, keycode);
  event.state = modifiers;

  if(press)
    event.type = KeyPress;
  else
    event.type = KeyRelease;

  return event;
}

// TODO: fail out if display doesn't initialize
X11Display::X11Display(const char* dispName)
{
  display = XOpenDisplay(dispName);
  if(NULL == display) {
    printf("invalid X11 display: %s\n", dispName);
    throw;
  }
  winRoot = XDefaultRootWindow(display);
}

X11Display::~X11Display() { XCloseDisplay(display); }

int X11Display::sendKeyEvent(int keycode, bool keyDown, int mod = 0)
{
  if(-1==keycode)
    return 0;
  Window winFocus;
  int revert;

  XGetInputFocus(display, &winFocus, &revert);
  XKeyEvent event = createKeyEvent(display, winFocus, winRoot, keyDown, keycode, mod);
  XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent*)&event);
  return 0;
}

bool IsModKey(int keycode) {
  switch(keycode){
    //shift, control and menu (both left and right) are consecutive
    case irr::KEY_LSHIFT ... irr::KEY_RMENU :
      return true;
    default :
      return false;
  }
}

int mapKeyCode(int irrcode){
  switch(irrcode){
    //FIXME: only to get rid of arrow spam
    case 37 ... 40:
      return -1;
    case irr::KEY_BACK :
      return XK_BackSpace;
    case irr::KEY_TAB :
      return XK_Tab;
    //FIXME: Should escape be a modifier too?
    case irr::KEY_ESCAPE :
      return XK_Escape;
    case irr::KEY_RETURN :
      return XK_Return;
    case irr::KEY_MINUS :
      return XK_minus;
    case irr::KEY_PLUS :
      return XK_equal;
    case irr::KEY_OEM_1 :
      return XK_semicolon;
    case irr::KEY_OEM_2 :
      return XK_slash;
    case irr::KEY_OEM_4 :
      return XK_bracketleft;
    case irr::KEY_OEM_6 :
      return XK_bracketright;
    case irr::KEY_OEM_7 :
      return XK_apostrophe;
    case irr::KEY_PERIOD :
      return XK_period;
    case irr::KEY_COMMA :
      return XK_comma;
    case irr::KEY_OEM_5 :
      return XK_backslash;
    case irr::KEY_LSHIFT :
      return XK_Shift_L;
    case irr::KEY_RSHIFT :
      return XK_Shift_R;
    case irr::KEY_LCONTROL :
      return XK_Control_L;
    case irr::KEY_RCONTROL :
      return XK_Control_R;
    default:
      return irrcode;
  }
}

<|endoftext|>