53 double y13 = node1.at(
yind) - node3.at(
yind);
54 double x24 = node2.at(
xind) - node4.at(
xind);
55 double y24 = node2.at(
yind) - node4.at(
yind);
57 return fabs( 0.5 * ( x13 * y24 - x24 * y13 ) );
63 double ksi = lcoords[0];
64 double eta = lcoords[1];
67 ( 1. + ksi ) * ( 1. + eta ) * 0.25,
68 ( 1. - ksi ) * ( 1. + eta ) * 0.25,
69 ( 1. - ksi ) * ( 1. - eta ) * 0.25,
70 ( 1. + ksi ) * ( 1. - eta ) * 0.25
77 answer =
evalN({lcoords[0], lcoords[1]});
80std::pair<double, FloatMatrixF<2,4>>
86 for ( std::size_t i = 0; i < dndu.cols(); i++ ) {
90 jacT(0, 0) += dndu(0, i) * x;
91 jacT(0, 1) += dndu(0, i) * y;
92 jacT(1, 0) += dndu(1, i) * x;
93 jacT(1, 1) += dndu(1, i) * y;
101 auto tmp =
evaldNdx(lcoords, cellgeo);
109 double ksi = lcoords.
at(1);
110 double eta = lcoords.
at(2);
112 double n1 = ( 1. + ksi ) * ( 1. + eta ) * 0.25;
113 double n2 = ( 1. - ksi ) * ( 1. + eta ) * 0.25;
114 double n3 = ( 1. - ksi ) * ( 1. - eta ) * 0.25;
115 double n4 = ( 1. + ksi ) * ( 1. - eta ) * 0.25;
123 n3 * p3.at(
xind) + n4 * p4.at(
xind),
124 n1 * p1.at(
yind) + n2 * p2.at(
yind) +
125 n3 * p3.at(
yind) + n4 * p4.at(
yind));
128#define POINT_TOL 1.e-6
133 double x1, x2, x3, x4, y1, y2, y3, y4, a1, a2, a3, a4, b1, b2, b3, b4;
134 double a, b, c, ksi1, ksi2, ksi3, eta1 = 0.0, eta2 = 0.0, denom;
149 a1 = x1 + x2 + x3 + x4;
150 a2 = x1 - x2 - x3 + x4;
151 a3 = x1 + x2 - x3 - x4;
152 a4 = x1 - x2 + x3 - x4;
154 b1 = y1 + y2 + y3 + y4;
155 b2 = y1 - y2 - y3 + y4;
156 b3 = y1 + y2 - y3 - y4;
157 b4 = y1 - y2 + y3 - y4;
159 a = a2 * b4 - b2 * a4;
160 b = a1 * b4 + a2 * b3 - a3 * b2 - b1 * a4 - b4 * 4.0 * coords.
at(
xind) + a4 * 4.0 * coords.
at(
yind);
161 c = a1 * b3 - a3 * b1 - 4.0 * coords.
at(
xind) * b3 + 4.0 * coords.
at(
yind) * a3;
164 cubic(0.0, a, b, c, & ksi1, & ksi2, & ksi3, & nroot);
172 denom = ( b3 + ksi1 * b4 );
173 if ( fabs(denom) <= 1.0e-10 ) {
174 eta1 = ( 4.0 * coords.
at(
xind) - a1 - ksi1 * a2 ) / ( a3 + ksi1 * a4 );
176 eta1 = ( 4.0 * coords.
at(
yind) - b1 - ksi1 * b2 ) / denom;
181 double diff_ksi1, diff_eta1, diff_ksi2, diff_eta2, diff1, diff2;
183 denom = b3 + ksi2 * b4;
184 if ( fabs(denom) <= 1.0e-10 ) {
185 eta2 = ( 4.0 * coords.
at(
xind) - a1 - ksi2 * a2 ) / ( a3 + ksi2 * a4 );
187 eta2 = ( 4.0 * coords.
at(
yind) - b1 - ksi2 * b2 ) / denom;
193 diff_ksi1 = ksi1 - 1.0;
197 diff_ksi1 = ksi1 + 1.0;
202 diff_eta1 = eta1 - 1.0;
206 diff_eta1 = eta1 + 1.0;
211 diff_ksi2 = ksi2 - 1.0;
215 diff_ksi2 = ksi2 + 1.0;
220 diff_eta2 = eta2 - 1.0;
224 diff_eta2 = eta2 + 1.0;
227 diff1 = diff_ksi1 * diff_ksi1 + diff_eta1 * diff_eta1;
228 diff2 = diff_ksi2 * diff_ksi2 + diff_eta2 * diff_eta2;
231 if ( diff1 > diff2 ) {
242 for (
int i = 1; i <= 2; i++ ) {
258 double ksi = lcoords.
at(1);
259 answer =
Vec2( ( 1. - ksi ) * 0.5, ( 1. + ksi ) * 0.5 );
266 int nodeA = edgeNodes.at(1);
267 int nodeB = edgeNodes.at(2);
283 answer =
Vec2( -1.0 / l, 1.0 / l );
287FEI2dQuadLin :: edgeLocal2global(
FloatArray &answer,
int iedge,
292 this->
edgeEvalN(n, iedge, lcoords, cellgeo);
302FEI2dQuadLin :: computeLocalEdgeMapping(
int iedge)
const
306 }
else if ( iedge == 2 ) {
308 }
else if ( iedge == 3 ) {
310 }
else if ( iedge == 4 ) {
313 throw std::range_error(
"invalid edge number");
321 int nodeA = edgeNodes.
at(1);
322 int nodeB = edgeNodes.
at(2);
326 return sqrt(dx * dx + dy * dy);
332 const double point_tol = 1.0e-3;
334 for (
int i = 1; i <= 2; i++ ) {
335 if ( lcoords.
at(i) < ( -1. - point_tol ) ) {
337 }
else if ( lcoords.
at(i) > ( 1. + point_tol ) ) {
347 const double &ksi = lcoords[0];
348 const double &eta = lcoords[1];
352 answer.
at(1, 1) = 0.25 * ( 1. + eta );
353 answer.
at(1, 2) = -0.25 * ( 1. + eta );
354 answer.
at(1, 3) = -0.25 * ( 1. - eta );
355 answer.
at(1, 4) = 0.25 * ( 1. - eta );
358 answer.
at(2, 1) = 0.25 * ( 1. + ksi );
359 answer.
at(2, 2) = 0.25 * ( 1. - ksi );
360 answer.
at(2, 3) = -0.25 * ( 1. - ksi );
361 answer.
at(2, 4) = -0.25 * ( 1. + ksi );
375 double x1 = node1.
at(
xind);
376 double y1 = node1.at(
yind);
379 double x2 = node2.
at(
xind);
380 double y2 = node2.at(
yind);
382 return -( x2 * y1 - x1 * y2 );
385std::unique_ptr<IntegrationRule>
388 auto iRule = std::make_unique<GaussIntegrationRule>(1,
nullptr);
389 int points = iRule->getRequiredNumberOfIntegrationPoints(
_Square,
order + 2);
390 iRule->SetUpPointsOnSquare(points, _Unknown);
391 return std::move(iRule);
402 this->
evalN(
N, lcoords, cellgeo);
405 for (
int i = 1; i <= 4; i++ ) {
419 this->
edgeEvalN(n, iedge, lcoords, cellgeo);
double boundaryEdgeGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
double edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
double boundaryGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
std::pair< double, FloatMatrixF< 2, 4 > > evaldNdx(const FloatArrayF< 2 > &lcoords, const FEICellGeometry &cellgeo) const
double edgeComputeLength(const IntArray &edgeNodes, const FEICellGeometry &cellgeo) const
static FloatMatrixF< 2, 4 > evaldNdxi(const FloatArrayF< 2 > &lcoords)
static FloatArrayF< 4 > evalN(const FloatArrayF< 2 > &lcoords)
bool inside(const FloatArray &lcoords) const override
IntArray computeLocalEdgeMapping(int iedge) const override
void edgeEvalN(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
virtual const FloatArray giveVertexCoordinates(int i) const =0
virtual double edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
void zero()
Zeroes all coefficients of receiver.
double normalize_giveNorm()
double at(std::size_t i, std::size_t j) const
static FloatArray Vec2(const double &a, const double &b)
FloatMatrixF< M, N > transpose(const FloatMatrixF< N, M > &mat)
Constructs transposed matrix.
double det(const FloatMatrixF< 2, 2 > &mat)
Computes the determinant.
double dot(const FloatArray &x, const FloatArray &y)
void cubic(double a, double b, double c, double d, double *r1, double *r2, double *r3, int *num)
FloatMatrixF< N, N > inv(const FloatMatrixF< N, N > &mat, double zeropiv=1e-24)
Computes the inverse.