Please take a look at this class and point out its flaws. I am developing a simple Finite Element Method analysis with PHP.
What this class basically does:
Given an input set (coordinates, properties, plane type), calculate an output/analysis set (area, matrix, etc.).
Possible hints on flaws:
- This is a full static class
- Takes array as input parameter, outputs an array too
- Perhaps the name is too long
If this code is considered a "good design pattern", I will use this similar approach to all other codes in my project.
<?php
class CSTElementStiffnessCalculator {
public static $sampleInput_StressIsotropic = array(
'planeType' => 'stress',
'firstNode' => array(
'x' => 100,
'y' => -6.25,
'id' => 2
),
'secondNode' => array(
'x' => 200,
'y' => -12.5,
'id' => 3
),
'thirdNode' => array(
'x' => 200,
'y' => 12.5,
'id' => 4
),
'property' => array(
'type' => 'isotropic',
'E' => 200,
'V' => 0.3,
'thickness' => 10
)
);
public static $sampleInput_StrainOrthotropic = array(
'planeType' => 'strain',
'firstNode' => array(
'x' => 0,
'y' => -6.25,
'id' => 1
),
'secondNode' => array(
'x' => 100,
'y' => -6.25,
'id' => 5
),
'thirdNode' => array(
'x' => 100,
'y' => 6.25,
'id' => 6
),
'property' => array(
'type' => 'orthotropic',
'Ex' => 200,
'Ey' => 100,
'Ez' => 50,
'Vxy' => 0.35,
'Vxz' => 0.3,
'Vyz' => 0.25,
'Gxy' => 50,
'thickness' => 1
)
);
public static function calculate($inputParams)
{
$x1 = $inputParams['firstNode']['x'];
$y1 = $inputParams['firstNode']['y'];
$id1 = $inputParams['firstNode']['id'];
$x2 = $inputParams['secondNode']['x'];
$y2 = $inputParams['secondNode']['y'];
$id2 = $inputParams['secondNode']['id'];
$x3 = $inputParams['thirdNode']['x'];
$y3 = $inputParams['thirdNode']['y'];
$id3 = $inputParams['thirdNode']['id'];
$planeType = $inputParams['planeType'];
$property = $inputParams['property'];
$thickness = $property['thickness'];
/////////////////////////////////////////////////////////////
$DoubleAMatrix = self::makeDoubleAMatrix(
$x1, $y1, $x2, $y2, $x3, $y3
);
$doubleA = $DoubleAMatrix->det();
$Area = $doubleA / 2;
$BMatrix = self::makeBMatrix(
$Area, $x2-$x1, $x3-$x2, $x1-$x3, $y2-$y1, $y3-$y2, $y1-$y3
);
$DMatrix = self::makeDMatrix(
$planeType, $property
);
/////////////////////////////////////////////////////////////
$BTrans = $BMatrix->transpose();
$tempMat = $BTrans->times($DMatrix); // [B]T x [D]
$tempMat = $tempMat->times($BMatrix); // [B]T x [D] x [B]
$tA = $thickness * $Area;
$KMatrix = $tempMat->times($tA); // t x A x [B]T x [D] x B
/////////////////////////////////////////////////////////////
$stiffnessIds = array();
$stiffnessIds[] = $id1 * 2 - 1;
$stiffnessIds[] = $id1 * 2;
$stiffnessIds[] = $id2 * 2 - 1;
$stiffnessIds[] = $id2 * 2;
$stiffnessIds[] = $id3 * 2 - 1;
$stiffnessIds[] = $id3 * 2;
/////////////////////////////////////////////////////////////
return array(
'd_matrix' => $DMatrix->getArrayCopy(),
'b_matrix' => $BMatrix->getArrayCopy(),
'area' => $Area,
'local_stiff_ids' => $stiffnessIds,
'local_stiff_matrix' => $KMatrix->getArrayCopy()
);
}
private static function makeDoubleAMatrix($x1, $y1, $x2, $y2, $x3, $y3)
{
$data = array(
array(1, $x1, $y1),
array(1, $x2, $y2),
array(1, $x3, $y3),
);
return new \Matrix($data);
}
private static function makeBMatrix($A, $x12, $x23, $x31, $y12, $y23, $y31)
{
$multiplier = 1 / (2 * $A);
$data = array(
array( -$y23, 0, -$y31, 0, -$y12, 0 ),
array( 0, $x23, 0, $x31, 0, $x12 ),
array( $x23, -$y23, $x31, -$y31, $x12, -$y12 ),
);
$matrix = new \Matrix($data);
return $matrix->times($multiplier);
}
private static function makeDMatrix($planeType, $property)
{
if ($planeType == 'stress' && $property['type'] == 'isotropic')
{
return self::makeDMatrix_Stress_Isotropic(
$property['E'],
$property['V']
);
}
if ($planeType == 'stress' && $property['type'] == 'orthotropic')
{
return self::makeDMatrix_Stress_Orthotropic(
$property['Ex'],
$property['Ey'],
$property['Vxy'],
$property['Gxy']
);
}
if ($planeType == 'strain' && $property['type'] == 'isotropic')
{
return self::makeDMatrix_Strain_Isotropic(
$property['E'],
$property['V']
);
}
if ($planeType == 'strain' && $property['type'] == 'orthotropic')
{
return self::makeDMatrix_Strain_Orthotropic(
$property['Ex'],
$property['Ey'],
$property['Ez'],
$property['Vxy'],
$property['Vxz'],
$property['Vyz'],
$property['Gxy']
);
}
}
private static function makeDMatrix_Stress_Isotropic($E, $V)
{
$multiplier = $E / ( 1 - $V * $V );
$data = array(
array( 1, $V, 0 ),
array( $V, 1, 0 ),
array( 0, 0, (1-$V)/2 ),
);
$matrix = new \Matrix($data);
return $matrix->times($multiplier);
}
///////////////////////////////////////////////////////////////
private static function makeDMatrix_Stress_Orthotropic($Ex, $Ey, $Vxy, $Gxy)
{
$n = $Ex / $Ey;
$temp = 1 - $n * $Vxy * $Vxy;
$v00 = $Ex/$temp;
$v01 = $v10 = $Vxy*$Ex/$temp;
$v11 = $Ey/$temp;
$data = array(
array( $v00, $v01, 0 ),
array( $v10, $v11, 0 ),
array( 0, 0, $Gxy ),
);
return new \Matrix($data);
}
///////////////////////////////////////////////////////////////
private static function makeDMatrix_Strain_Isotropic($E, $V)
{
$multiplier = $E / ( ( 1 + $V ) * ( 1 - 2*$V ) );
$v22 = ( 1 - 2*$V ) / 2;
$data = array(
array( 1-$V, $V, 0 ),
array( $V, 1-$V, 0 ),
array( 0, 0, $v22 ),
);
$matrix = new \Matrix($data);
return $matrix->times($multiplier);
}
///////////////////////////////////////////////////////////////
private static function makeDMatrix_Strain_Orthotropic($Ex, $Ey, $Ez, $Vxy, $Vxz, $Vyz, $Gxy)
{
$D = ( 1 - $Vxz * $Vxz * ($Ex/$Ez) ) * ( 1 - $Vyz * $Vyz * ($Ey/$Ez) ) -
( $Vxy + $Vxz * $Vyz * ($Ey/$Ez) ) * ( $Vxy * ($Ex/$Ey) + $Vyz * $Vxz * ($Ex/$Ez));
$n = 1 / $D;
$v00 = $n * ( 1 - $Vyz * $Vyz * ($Ey/$Ez) ) * $Ex;
$v01 = $n * ( $Vxy + $Vxz * $Vyz * ($Ey/$Ez) ) * $Ex;
$v10 = $n * ( $Vxy * ($Ex/$Ey) + $Vyz * $Vxz * ($Ex/$Ez) ) * $Ey;
$v11 = $n * ( 1 - $Vxz * $Vxz * ($Ex/$Ez) ) * $Ey;
$data = array(
array( $v00, $v01, 0 ),
array( $v10, $v11, 0 ),
array( 0, 0, $Gxy ),
);
return new \Matrix($data);
}
}