The problem:
- A
Node
is located in a specific coordinate (x, y, z). - A
Node
can be one of these types:None
,Hinge
,Roll
,Fixed
. (it is called Boundary Condition) Different boundary condition type determine aNode
's Degree of Freedom.
I have one Abstract NodeBase
class and multiple classes of nodes inheriting them. Please check if this is a good approach.
I also have some Abstract Data Types, such as Coordinate
, ForceSet
, DisplacementSet
. They are classes containing only public variables. (want to use them as struct
s, like in C++)
NodeBase.php:
abstract class NodeBase {
/** @var Coordinate */
protected $coordinate;
/** @var ForceSet */
protected $forces;
/** @var DisplacementSet */
protected $displacements;
/** @var int index / ordering of this node in a project */
protected $idNumber;
/** @var int static variable, giving each node a unique Id Number */
private static $idCounter = 0;
/** @var double $localAngle local rotation of the node */
protected $localAngle;
public function __construct(array $params = null)
{
// For Generating ID Numbers (starting from 1)
self::$idCounter++;
// Initialization
$this->coordinate = new Coordinate();
$this->forces = new ForceSet();
$this->displacements = new DisplacementSet();
$this->idNumber = self::$idCounter;
// Assign values with parameter (if exists)
if (isset($params))
{
if (isset($params['x']))
{
$this->coordinate->x = $params['x'];
}
if (isset($params['y']))
{
$this->coordinate->y = $params['y'];
}
if (isset($params['angle']))
{
$this->localAngle = $params['angle'];
}
}
}
public function setCoordXY($x, $y)
{
$this->coordinate->x = $x;
$this->coordinate->y = $y;
}
public function setCoordXYZ($x, $y, $z)
{
$this->coordinate->x = $x;
$this->coordinate->y = $y;
$this->coordinate->z = $z;
}
public function getX()
{
return $this->coordinate->x;
}
public function getY()
{
return $this->coordinate->y;
}
public function getZ()
{
return $this->coordinate->z;
}
public function getIdNumber()
{
return $this->idNumber;
}
public function getAngle()
{
return $this->localAngle;
}
public function setAngle($angle)
{
$this->localAngle = $angle;
}
public function getAngleMatrix()
{
return array(
array(1, 0),
array(0, 1),
);
}
/**
* @param String[] $forceNames available values = 'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'
* @return SimpleEquation[] forces retrieved (array of SimpleEquations)
*/
public function getForces(array $forceNames)
{
$result = array();
$forcesArray = get_object_vars($this->forces);
foreach ($forceNames as $fName)
{ /** @var $fName String */
$result = $forcesArray[$fName];
}
return $result;
}
/**
* @param String[] $forceNames available values = 'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'
* @return String[] forces retrieved (array of Strings)
*/
public function getForcesString(array $forceNames)
{
$forces = $this->getForces($forceNames);
$result = array();
foreach ($forces as $f)
{ /** @var $f SimpleEquation */
$result[] = $f->getString();
}
return $result;
}
/**
* @param String[] $dispNames available values = 'dx', 'dy', 'dz', 'Ox', 'Oy', 'Oz'
* @return SimpleEquation[] displacements retrieved (array of SimpleEquations)
*/
public function getDisplacements(array $dispNames)
{
$result = array();
$dispArray = get_object_vars($this->displacements);
foreach ($dispNames as $dName)
{ /** @var $dName String */
$result = $dispArray[$dName];
}
return $result;
}
/**
* @param String[] $dispNames available values = 'dx', 'dy', 'dz', 'Ox', 'Oy', 'Oz'
* @return String[] displacements retrieved (array of Strings)
*/
public function getDisplacementsString(array $dispNames)
{
$displacements = $this->getDisplacements($dispNames);
$result = array();
foreach ($displacements as $d)
{ /** @var $d SimpleEquation */
$result[] = $d->getEquation();
}
return $result;
}
public function addForceValue($forceName, $value)
{
$this->getForce($forceName)->addValue($value);
}
public function solveForce($forceName, $value)
{
$this->getForce($forceName)->solve($value);
}
public function solveDisplacementValue($dispName, $value)
{
$this->getDisplacement($dispName)->solve($value);
}
public function getForce($forceName)
{
switch ($forceName)
{
case 'Fx':
return $this->forces->Fx;
case 'Fy':
return $this->forces->Fy;
case 'Fz':
return $this->forces->Fz;
case 'Mx':
return $this->forces->Mx;
case 'My':
return $this->forces->My;
case 'Mz':
return $this->forces->Mz;
}
}
public function getDisplacement($dispName)
{
switch ($dispName)
{
case 'dx':
return $this->displacements->dx;
case 'dy':
return $this->displacements->dy;
case 'dz':
return $this->displacements->dz;
case 'Ox':
return $this->displacements->Ox;
case 'Oy':
return $this->displacements->Oy;
case 'Oz':
return $this->displacements->Oz;
}
}
}
NoneNode.php:
class NoneNode extends NodeBase {
public function __construct(array $params = null)
{
parent::__construct($params);
$this->forces->Fx = new SimpleEquation(SimpleEquation::KNOWN_VALUE, 'Fx');
$this->forces->Fy = new SimpleEquation(SimpleEquation::KNOWN_VALUE, 'Fy');
$this->forces->Mz = new SimpleEquation(SimpleEquation::KNOWN_VALUE, 'Mz');
$this->displacements->dx = new SimpleEquation(SimpleEquation::UNKNOWN_VALUE, 'dx');
$this->displacements->dy = new SimpleEquation(SimpleEquation::UNKNOWN_VALUE, 'dy');
$this->displacements->Oz = new SimpleEquation(SimpleEquation::UNKNOWN_VALUE, 'Oz');
}
}
HingeNode.php:
class HingeNode extends NodeBase {
public function __construct(array $params = null)
{
parent::__construct($params);
$this->forces->Fx = new SimpleEquation(SimpleEquation::UNKNOWN_VALUE, 'Fx');
$this->forces->Fy = new SimpleEquation(SimpleEquation::UNKNOWN_VALUE, 'Fy');
$this->forces->Mz = new SimpleEquation(SimpleEquation::KNOWN_VALUE, 'Mz');
$this->displacements->dx = new SimpleEquation(SimpleEquation::KNOWN_VALUE, 'dx');
$this->displacements->dy = new SimpleEquation(SimpleEquation::KNOWN_VALUE, 'dy');
$this->displacements->Oz = new SimpleEquation(SimpleEquation::UNKNOWN_VALUE, 'Oz');
}
}
I have two other classes: FixedNode
and RollNode
that I don't list them here, because they are very similar to both of NoneNode
and HingeNode
.
1 Answer 1
It all looks good to me, though you can simplify your NodeBase getForce()
and getDisplacement()
methods if you use variable properties, like so:
public function getForce($forceName)
{
if(isset($this->forces->$forceName))
{
return $this->forces->$forceName;
}
}
public function getDisplacement($dispName)
{
if(isset($this->displacements->$dispName))
{
return $this->displacements->$dispName;
}
}
Which will save you a lot of rewriting if you decide to change the names of any of the properties down the line