OOFEM 3.0
Loading...
Searching...
No Matches
quad1mindlin.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
38#include "node.h"
39#include "material.h"
40#include "crosssection.h"
41#include "gausspoint.h"
43#include "floatmatrix.h"
44#include "floatarray.h"
45#include "intarray.h"
46#include "load.h"
47#include "mathfem.h"
48#include "fei2dquadlin.h"
49#include "classfactory.h"
50#include "parametermanager.h"
51#include "paramkey.h"
52
53namespace oofem {
56
58
66
69{
70 return & interp_lin;
71}
72
78
79void
81{
82 if ( integrationRulesArray.size() == 0 ) {
83 integrationRulesArray.resize(1);
84 integrationRulesArray [ 0 ] = std::make_unique< GaussIntegrationRule >(1, this, 1, 5);
86 }
87}
88
89
90void
91Quad1Mindlin::computeBodyLoadVectorAt(FloatArray &answer, Load *forLoad, TimeStep *tStep, ValueModeType mode)
92{
93 // Only gravity load
94 FloatArray gravity;
95
96 if ( ( forLoad->giveBCGeoType() != BodyLoadBGT ) || ( forLoad->giveBCValType() != ForceLoadBVT ) ) {
97 OOFEM_ERROR("unknown load type");
98 }
99
100 // note: force is assumed to be in global coordinate system.
101 forLoad->computeComponentArrayAt(gravity, tStep, mode);
102
103 if ( gravity.giveSize() ) {
104 FloatArrayF< 4 >force;
106 for ( auto &gp: * integrationRulesArray [ 0 ] ) {
107 auto n = this->interp_lin.evalN( gp->giveNaturalCoordinates() );
108 double dV = this->computeVolumeAround(gp) * this->giveCrossSection()->give(CS_Thickness, gp);
109 double load = this->giveStructuralCrossSection()->give('d', gp) * gravity.at(3) * dV;
110 force += load * n;
111 }
112
113 answer.resize(12);
114 answer.zero();
115 answer.at(1) = force.at(1);
116 answer.at(4) = force.at(2);
117 answer.at(7) = force.at(3);
118 answer.at(10) = force.at(4);
119 } else {
120 answer.clear();
121 }
122}
123
124
125void
127// Returns the [5x9] strain-displacement matrix {B} of the receiver,
128// evaluated at gp.
129{
130 auto dn = this->interp_lin.evaldNdx( gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ).second;
131 auto n = this->interp_lin.evalN( gp->giveNaturalCoordinates() );
132
133 // enforce one-point reduced integration if requested
136 if ( this->reducedIntegrationFlag ) {
137 FloatArrayF< 2 >lc; // set to element center coordinates
138 dns = this->interp_lin.evaldNdx( lc, FEIElementGeometryWrapper(this) ).second;
139 ns = this->interp_lin.evalN(lc);
140 } else {
141 dns = dn;
142 ns = n;
143 }
144
145 answer.resize(5, 12);
146 answer.zero();
147
149 for ( int i = 0; i < 4; ++i ) {
150 answer(0, 2 + i * 3) = dn(0, i);// kappa_x = d(fi_y)/dx
151 answer(1, 1 + i * 3) = -dn(1, i); // kappa_y = -d(fi_x)/dy
152 answer(2, 2 + i * 3) = dn(1, i);// kappa_xy=d(fi_y)/dy-d(fi_x)/dx
153 answer(2, 1 + i * 3) = -dn(0, i);
154
155 answer(3, 0 + i * 3) = dns(0, i); // gamma_xz = fi_y+dw/dx
156 answer(3, 2 + i * 3) = ns [ i ];
157 answer(4, 0 + i * 3) = dns(1, i);// gamma_yz = -fi_x+dw/dy
158 answer(4, 1 + i * 3) = -ns [ i ];
159 }
160}
161
162
163void
165{
166 answer = this->giveStructuralCrossSection()->giveGeneralizedStress_Plate(strain, gp, tStep);
167}
168
169
170void
172{
173 answer = this->giveStructuralCrossSection()->give2dPlateStiffMtrx(rMode, gp, tStep);
174}
175
176
177void
184
185
186void
188{
189 answer = { D_w, R_u, R_v };
190}
191
192
193void
195{
198
199 auto n = cross(u, v);
200 answer = n / norm(n);
201}
202
203
204double
206{
207 return this->giveCharacteristicLengthForPlaneElements(normalToCrackPlane);
208}
209
210
211double
213{
214 double weight = gp->giveWeight();
215 double detJ = fabs(this->interp_lin.giveTransformationJacobian(gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ) );
216 return detJ * weight;
217}
218
219
220void
222// Returns the lumped mass matrix of the receiver.
223{
225 double mass = 0.;
226 for ( GaussPoint *gp: * integrationRulesArray [ 0 ] ) {
227 double dV = this->computeVolumeAround(gp)*this->giveCrossSection()->give(CS_Thickness, gp);
228 mass += dV * this->giveStructuralCrossSection()->give('d', gp);
229 }
230
231 answer.resize(12, 12);
232 answer.zero();
233 answer.at(1, 1) = mass * 0.25;
234 answer.at(4, 4) = mass * 0.25;
235 answer.at(7, 7) = mass * 0.25;
236 answer.at(10, 10) = mass * 0.25;
237}
238
239
240int
242{
243 answer.resize(6);
244 auto ms = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() );
245 if ( type == IST_ShellForceTensor || type == IST_ShellStrainTensor ) {
246 const auto &s = type == IST_ShellForceTensor ? ms->giveStressVector() : ms->giveStrainVector();
247 answer.at(1) = 0.0; // nx
248 answer.at(2) = 0.0; // ny
249 answer.at(3) = 0.0; // nz
250 answer.at(4) = s.at(5); // vyz
251 answer.at(5) = s.at(4); // vxz
252 answer.at(6) = 0.0; // vxy
253 return 1;
254 } else if ( type == IST_ShellMomentTensor || type == IST_CurvatureTensor ) {
255 const auto &s = type == IST_ShellMomentTensor ? ms->giveStressVector() : ms->giveStrainVector();
256 answer.at(1) = s.at(1); // mx
257 answer.at(2) = s.at(2); // my
258 answer.at(3) = 0.0; // mz
259 answer.at(4) = 0.0; // myz
260 answer.at(5) = 0.0; // mxz
261 answer.at(6) = s.at(3); // mxy
262 return 1;
263 } else {
264 return StructuralElement::giveIPValue(answer, gp, type, tStep);
265 }
266}
267
268void
270{
271 if ( iEdge == 1 ) { // edge between nodes 1 2
272 answer = { 1, 2, 3, 4, 5, 6 };
273 } else if ( iEdge == 2 ) { // edge between nodes 2 3
274 answer = { 4, 5, 6, 7, 8, 9 };
275 } else if ( iEdge == 3 ) { // edge between nodes 3 4
276 answer = { 7, 8, 9, 10, 11, 12 };
277 } else if ( iEdge == 4 ) { // edge between nodes 4 1
278 answer = { 10, 11, 12, 1, 2, 3 };
279 } else {
280 OOFEM_ERROR("wrong edge number");
281 }
282}
283
284
285double
287{
288 double detJ = this->interp_lin.edgeGiveTransformationJacobian(iEdge, gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) );
289 return detJ * gp->giveWeight();
290}
291
292
293int
295{
296 const auto &edgeNodes = this->interp_lin.computeLocalEdgeMapping(iEdge);
297
298 auto nodeA = this->giveNode(edgeNodes.at(1) );
299 auto nodeB = this->giveNode(edgeNodes.at(2) );
300
301 double dx = nodeB->giveCoordinate(1) - nodeA->giveCoordinate(1);
302 double dy = nodeB->giveCoordinate(2) - nodeA->giveCoordinate(2);
303 double length = sqrt(dx * dx + dy * dy);
304
305 answer.resize(3, 3);
306 answer.zero();
307 answer.at(1, 1) = 1.0;
308 answer.at(2, 2) = dx / length;
309 answer.at(2, 3) = -dy / length;
310 answer.at(3, 2) = -answer.at(2, 3);
311 answer.at(3, 3) = answer.at(2, 2);
312
313 return 1;
314}
315Interface *
317{
318 if ( interface == ZZNodalRecoveryModelInterfaceType ) {
319 return static_cast< ZZNodalRecoveryModelInterface * >( this );
320 } else if ( interface == SPRNodalRecoveryModelInterfaceType ) {
321 return static_cast< SPRNodalRecoveryModelInterface * >( this );
322 }
323
324 return nullptr;
325}
326
327
328
329void
331{
332 pap.resize(4);
333 for ( int i = 1; i < 5; i++ ) {
334 pap.at(i) = this->giveNode(i)->giveNumber();
335 }
336}
337
338void
340{
341 int found = 0;
342 answer.resize(1);
343
344 for ( int i = 1; i < 5; i++ ) {
345 if ( pap == this->giveNode(i)->giveNumber() ) {
346 found = 1;
347 }
348 }
349
350 if ( found ) {
351 answer.at(1) = pap;
352 } else {
353 OOFEM_ERROR("node unknown");
354 }
355}
356} // end namespace oofem
double length(const Vector &a)
Definition CSG.h:88
#define REGISTER_Element(class)
virtual double give(CrossSectionProperty a, GaussPoint *gp) const
virtual int setupIntegrationPoints(IntegrationRule &irule, int npoints, Element *element)
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
ParameterManager elementPPM
Definition domain.h:133
Node * giveNode(int i) const
Definition element.h:629
void initializeFrom(InputRecord &ir, int priority) override
Definition element.C:687
int numberOfDofMans
Number of dofmanagers.
Definition element.h:136
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
Definition element.h:157
int numberOfGaussPoints
Definition element.h:175
double giveCharacteristicLengthForPlaneElements(const FloatArray &normalToCrackPlane)
Definition element.C:1188
CrossSection * giveCrossSection()
Definition element.C:534
Domain * giveDomain() const
Definition femcmpnn.h:97
int number
Component number.
Definition femcmpnn.h:77
int giveNumber() const
Definition femcmpnn.h:104
double & at(std::size_t i)
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
const FloatArray & giveNaturalCoordinates() const
Returns coordinate array of receiver.
Definition gausspoint.h:138
IntegrationPointStatus * giveMaterialStatus(IntegrationPointStatusIDType key=IPSID_Default)
Definition gausspoint.h:204
double giveWeight()
Returns integration weight of receiver.
Definition gausspoint.h:180
virtual bcGeomType giveBCGeoType() const
void resize(int n)
Definition intarray.C:73
int & at(std::size_t i)
Definition intarray.h:104
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
Definition load.C:84
void SPRNodalRecoveryMI_giveDofMansDeterminedByPatch(IntArray &answer, int pap) override
Interface * giveInterface(InterfaceType it) override
Quad1Mindlin(int n, Domain *d)
double giveCharacteristicLength(const FloatArray &normalToCrackPlane) override
void computeGaussPoints() override
FEInterpolation * giveInterpolation() const override
void giveEdgeDofMapping(IntArray &answer, int iEdge) const override
void SPRNodalRecoveryMI_giveSPRAssemblyPoints(IntArray &pap) override
void computeConstitutiveMatrixAt(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) override
double computeVolumeAround(GaussPoint *gp) override
void initializeFrom(InputRecord &ir, int priority) override
int computeLoadLEToLRotationMatrix(FloatMatrix &answer, int iEdge, GaussPoint *gp) override
void giveDofManDofIDMask(int inode, IntArray &) const override
void computeStressVector(FloatArray &answer, const FloatArray &strain, GaussPoint *gp, TimeStep *tStep) override
double computeEdgeVolumeAround(GaussPoint *gp, int iEdge) override
void computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int=1, int=ALL_STRAINS) override
void computeLumpedMassMatrix(FloatMatrix &answer, TimeStep *tStep) override
bool reducedIntegrationFlag
Flag controlling reduced (one - point) integration for shear.
static FEI2dQuadLin interp_lin
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
static ParamKey IPK_Quad1Mindlin_reducedIntegration
void computeMidPlaneNormal(FloatArray &answer, const GaussPoint *gp) override
void computeBodyLoadVectorAt(FloatArray &answer, Load *load, TimeStep *tStep, ValueModeType mode) override
virtual FloatMatrixF< 5, 5 > give2dPlateStiffMtrx(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const =0
virtual FloatArrayF< 5 > giveGeneralizedStress_Plate(const FloatArrayF< 5 > &generalizedStrain, GaussPoint *gp, TimeStep *tStep) const =0
StructuralCrossSection * giveStructuralCrossSection()
Helper function which returns the structural cross-section for the element.
StructuralElement(int n, Domain *d)
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
ZZNodalRecoveryModelInterface(Element *element)
Constructor.
#define OOFEM_ERROR(...)
Definition error.h:79
double norm(const FloatArray &x)
@ CS_Thickness
Thickness.
@ BodyLoadBGT
Distributed body load.
Definition bcgeomtype.h:43
FloatArrayF< 3 > cross(const FloatArrayF< 3 > &x, const FloatArrayF< 3 > &y)
Computes $ x \cross y $.
@ ForceLoadBVT
Definition bcvaltype.h:43
@ SPRNodalRecoveryModelInterfaceType
@ ZZNodalRecoveryModelInterfaceType
#define PM_CHECK_FLAG_AND_REPORT(_pm, _ir, _componentnum, _paramkey, _prio, _flag)

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011