OOFEM 3.0
Loading...
Searching...
No Matches
structuralinterfaceelement.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
39#include "feinterpol.h"
40#include "domain.h"
41#include "material.h"
42#include "gausspoint.h"
44#include "intarray.h"
45#include "floatarray.h"
46#include "floatmatrix.h"
47#include "mathfem.h"
48
49
50
51namespace oofem {
52StructuralInterfaceElement :: StructuralInterfaceElement(int n, Domain *aDomain) : Element(n, aDomain)
53{
54}
55
56int StructuralInterfaceElement :: computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
57{
59 FEInterpolation *interp = this->giveInterpolation();
60 interp->evalN( N, lcoords, FEIElementGeometryWrapper(this) );
61
62 answer.resize(this->giveDofManager(1)->giveCoordinates().giveSize());
63 answer.zero();
64
65 int numNodes = this->giveNumberOfNodes();
66 for ( int i = 1; i <= numNodes/2; i++ ) {
67 const auto &nodeCoord = this->giveDofManager(i)->giveCoordinates();
68 answer.add(N.at(i), nodeCoord );
69 }
70
71 return true;
72}
73
74
75void
76StructuralInterfaceElement :: computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
77{
78 // Computes the stiffness matrix of the receiver K_cohesive = int_A ( N^t * dT/dj * N ) dA
79 FloatMatrix N, D, DN;
80 bool matStiffSymmFlag = this->giveCrossSection()->isCharacteristicMtrxSymmetric(rMode);
81 answer.clear();
82
83 FloatMatrix rotationMatGtoL;
84 for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
85
86 if ( this->nlGeometry == 0 ) {
87 this->giveStiffnessMatrix_Eng(D, rMode, ip, tStep);
88 } else if ( this->nlGeometry == 1 ) {
89 this->giveStiffnessMatrix_dTdj(D, rMode, ip, tStep);
90 } else {
91 OOFEM_ERROR("nlgeometry must be 0 or 1!")
92 }
93
94 this->computeTransformationMatrixAt(ip, rotationMatGtoL);
95 D.rotatedWith(rotationMatGtoL, 'n'); // transform stiffness to global coord system
96
97 this->computeNmatrixAt(ip, N);
98 DN.beProductOf(D, N);
99 double dA = this->computeAreaAround(ip);
100 if ( matStiffSymmFlag ) {
101 answer.plusProductSymmUpper(N, DN, dA);
102 } else {
103 answer.plusProductUnsym(N, DN, dA);
104 }
105 }
106
107
108 if ( matStiffSymmFlag ) {
109 answer.symmetrized();
110 }
111}
112
113
114void
115StructuralInterfaceElement :: computeSpatialJump(FloatArray &answer, IntegrationPoint *ip, TimeStep *tStep)
116{
117 // Computes the spatial jump vector at the Gauss point (ip) of
118 // the receiver, at time step (tStep). jump = N*u
120 FloatArray u;
121
122 if ( !this->isActivated(tStep) ) {
123 //match dimensions
124 //answer.resize(3);
125 this->computeNmatrixAt(ip, N);
126 answer.resize(N.giveNumberOfRows());
127 answer.zero();
128 return;
129 }
130
131 this->computeNmatrixAt(ip, N);
132 this->computeVectorOf(VM_Total, tStep, u);
133
134 // subtract initial displacements, if defined
135 if ( initialDisplacements.giveSize() ) {
137 }
138
139 answer.beProductOf(N, u);
140}
141
142
143void
144StructuralInterfaceElement :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
145{
146 // Computes internal forces
147 // if useGpRecord == 1 then data stored in ip->giveStressVector() are used
148 // instead computing stressVector through this->ComputeStressVector();
149 // this must be done after you want internal forces after element->updateYourself()
150 // has been called for the same time step.
151
153 FloatArray u, traction, jump;
154
155 this->computeVectorOf(VM_Total, tStep, u); //u in GCS (LCS only if defined computeGtoLRotationMatrix() )
156 // subtract initial displacements, if defined
157 if ( initialDisplacements.giveSize() ) {
159 }
160
161 // zero answer will resize accordingly when adding first contribution
162 answer.clear();
163
164 for ( auto &ip: *this->giveDefaultIntegrationRulePtr() ) {
165 this->computeNmatrixAt(ip, N);
166 //if ( useUpdatedGpRecord == 1 ) {
167 // StructuralInterfaceMaterialStatus *status = static_cast< StructuralInterfaceMaterialStatus * >( ip->giveMaterialStatus() );
168 // //temp
169 // FloatArray traction3d;
170 // traction3d = status->giveTraction();
171 // traction.setValues(2, traction3d.at(1), traction3d.at(3) );
172 //} else {
173 jump.beProductOf(N, u);
174 this->computeTraction(traction, ip, jump, tStep);
175 //}
176
177 // compute internal cohesive forces as f = N^T*traction dA
178 double dA = this->computeAreaAround(ip);
179 answer.plusProduct(N, traction, dA);
180 }
181
182}
183
184
185void
186StructuralInterfaceElement :: computeTraction(FloatArray &traction, IntegrationPoint *ip, const FloatArray &jump, TimeStep *tStep)
187{
188 // Returns the traction in global coordinate system
189 FloatMatrix rotationMatGtoL, F;
190 this->computeTransformationMatrixAt(ip, rotationMatGtoL);
191
192 FloatArray jumpRot = jump;
193 jumpRot.rotatedWith(rotationMatGtoL, 'n'); // transform jump to local coord system
194
195 if ( this->nlGeometry == 0 ) {
196 this->giveEngTraction(traction, ip, jumpRot, tStep);
197 } else if ( this->nlGeometry == 1 ) {
199 F.beUnitMatrix();
200 F.rotatedWith(rotationMatGtoL, 'n');
201 this->giveFirstPKTraction(traction, ip, jumpRot, F, tStep);
202 }
203
205 FloatArray normal = {rotationMatGtoL.at(2,1), rotationMatGtoL.at(2,2), 0.};
206// printf("normal: "); normal.printYourself();
207 status->letNormalBe(normal);
208
209 traction.rotatedWith(rotationMatGtoL, 't'); // transform traction to global coord system
210}
211
212
213void
214StructuralInterfaceElement :: giveCharacteristicMatrix(FloatMatrix &answer, CharType mtrx, TimeStep *tStep)
215{
216 // returns characteristics matrix of receiver according to mtrx
217
218 if ( mtrx == TangentStiffnessMatrix ) {
219 this->computeStiffnessMatrix(answer, TangentStiffness, tStep);
220 } else if ( mtrx == SecantStiffnessMatrix ) {
221 this->computeStiffnessMatrix(answer, SecantStiffness, tStep);
222 } else if ( mtrx == ElasticStiffnessMatrix ) {
223 this->computeStiffnessMatrix(answer, ElasticStiffness, tStep);
224 } else {
225 OOFEM_ERROR("Unknown Type of characteristic mtrx (%s)", __CharTypeToString(mtrx) );
226 }
227}
228
229
230
231void
232StructuralInterfaceElement :: giveCharacteristicVector(FloatArray &answer, CharType mtrx, ValueModeType mode,
233 TimeStep *tStep)
234//
235// returns characteristics vector of receiver according to mtrx
236//
237{
238 if ( ( mtrx == InternalForcesVector ) && ( mode == VM_Total ) ) {
239 this->giveInternalForcesVector(answer, tStep);
240 } else if ( ( mtrx == LastEquilibratedInternalForcesVector ) && ( mode == VM_Total ) ) {
241 /* here tstep is not relevant, we set useUpdatedGpRecord = 1
242 * and this will cause to integrate internal forces using existing (nontemp, equlibrated) stresses in
243 * statuses. Mainly used to compute reaction forces */
244 this->giveInternalForcesVector(answer, tStep, 1);
245 } else if (mtrx == ExternalForcesVector ) {
246 answer.clear();
247 } else {
248 OOFEM_ERROR("Unknown Type of characteristic mtrx (%s)", __CharTypeToString(mtrx) );
249 }
250}
251
252void
253StructuralInterfaceElement :: updateYourself(TimeStep *tStep)
254{
255 Element :: updateYourself(tStep);
256
257 // record initial displacement if element not active
258 if ( activityTimeFunction && !isActivated(tStep) ) {
259 this->computeVectorOf(VM_Total, tStep, initialDisplacements);
260 }
261}
262
263
264void
265StructuralInterfaceElement :: updateInternalState(TimeStep *tStep)
266{
267 // Updates the receiver at end of step.
268 FloatArray tractionG, jumpL;
269
270 // force updating strains & stresses
271 for ( auto &iRule: integrationRulesArray ) {
272 for ( GaussPoint *gp: *iRule ) {
273 this->computeSpatialJump(jumpL, gp, tStep);
274 this->computeTraction(tractionG, gp, jumpL, tStep);
275 }
276 }
277}
278
279
280int
281StructuralInterfaceElement :: checkConsistency()
282{
283 // check if the cross section is a 'StructuralInterfaceCrossSection'
284 if ( !this->giveInterfaceCrossSection()->testCrossSectionExtension(this->giveInterfaceCrossSection()->crossSectionType) ) {
285 OOFEM_WARNING("cross section %s is not a structural interface cross section", this->giveCrossSection()->giveClassName() );
286 return 0;
287 }
288 return this->giveInterfaceCrossSection()->checkConsistency();
289}
290
291
292int
293StructuralInterfaceElement :: giveIPValue(FloatArray &answer, IntegrationPoint *aIntegrationPoint, InternalStateType type, TimeStep *tStep)
294{
295 return Element :: giveIPValue(answer, aIntegrationPoint, type, tStep);
296}
297
298
299void StructuralInterfaceElement :: giveInputRecord(DynamicInputRecord &input)
300{
301 Element :: giveInputRecord(input);
302}
303
304
305StructuralInterfaceCrossSection *StructuralInterfaceElement :: giveInterfaceCrossSection()
306{
307 return static_cast< StructuralInterfaceCrossSection * >( this->giveCrossSection() );
308}
309
310
311void
312StructuralInterfaceElement :: giveEngTraction(FloatArray &answer, GaussPoint *gp, const FloatArray &jump, TimeStep *tStep)
313{
314 // Default implementation uses the First PK version if available.
317 FloatMatrix F(3, 3);
318 F.beUnitMatrix();
319 this->giveFirstPKTraction(answer, gp, jump, F, tStep);
320 // T_PK2 = inv(F)* T_PK1
321}
322
323
324void
325StructuralInterfaceElement :: giveStiffnessMatrix_Eng(FloatMatrix &answer, MatResponseMode rMode, IntegrationPoint *ip, TimeStep *tStep)
326{
327 // Default implementation uses the First PK version if available
328 this->giveStiffnessMatrix_dTdj(answer, rMode, ip, tStep);
330}
331} // end namespace oofem
332
#define N(a, b)
virtual bool isActivated(TimeStep *tStep)
Definition element.C:838
virtual FEInterpolation * giveInterpolation() const
Definition element.h:648
virtual int giveNumberOfNodes() const
Definition element.h:703
int activityTimeFunction
Element activity time function. If defined, nonzero value indicates active receiver,...
Definition element.h:163
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Definition element.C:103
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
Definition element.h:157
DofManager * giveDofManager(int i) const
Definition element.C:553
CrossSection * giveCrossSection()
Definition element.C:534
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Definition element.h:886
Element(int n, Domain *aDomain)
Definition element.C:86
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
void resize(Index s)
Definition floatarray.C:94
void plusProduct(const FloatMatrix &b, const FloatArray &s, double dV)
Definition floatarray.C:288
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void rotatedWith(FloatMatrix &r, char mode)
Definition floatarray.C:814
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void add(const FloatArray &src)
Definition floatarray.C:218
void subtract(const FloatArray &src)
Definition floatarray.C:320
void rotatedWith(const FloatMatrix &r, char mode='n')
void plusProductSymmUpper(const FloatMatrix &a, const FloatMatrix &b, double dV)
*Sets size of receiver to be an empty matrix It will have zero rows and zero columns size void clear()
void plusProductUnsym(const FloatMatrix &a, const FloatMatrix &b, double dV)
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
double at(std::size_t i, std::size_t j) const
void beUnitMatrix()
Sets receiver to unity matrix.
IntegrationPointStatus * giveMaterialStatus(IntegrationPointStatusIDType key=IPSID_Default)
Definition gausspoint.h:204
FloatArray initialDisplacements
Initial displacement vector, describes the initial nodal displacements when element has been casted.
bool nlGeometry
Flag indicating if geometrical nonlinearities apply.
virtual void computeTransformationMatrixAt(GaussPoint *gp, FloatMatrix &answer)=0
virtual void computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
StructuralInterfaceCrossSection * giveInterfaceCrossSection()
virtual void computeSpatialJump(FloatArray &answer, GaussPoint *gp, TimeStep *tStep)
virtual double computeAreaAround(GaussPoint *gp)=0
virtual void giveStiffnessMatrix_Eng(FloatMatrix &answer, MatResponseMode rMode, IntegrationPoint *ip, TimeStep *tStep)
virtual void giveEngTraction(FloatArray &answer, GaussPoint *gp, const FloatArray &jump, TimeStep *tStep)
const char * giveClassName() const override
virtual void giveStiffnessMatrix_dTdj(FloatMatrix &answer, MatResponseMode rMode, IntegrationPoint *ip, TimeStep *tStep)
virtual void computeNmatrixAt(GaussPoint *gp, FloatMatrix &answer)=0
virtual void computeTraction(FloatArray &traction, IntegrationPoint *ip, const FloatArray &jump, TimeStep *tStep)
virtual void giveFirstPKTraction(FloatArray &answer, GaussPoint *gp, const FloatArray &jump, const FloatMatrix &F, TimeStep *tStep)
virtual int testCrossSectionExtension(CrossSectExtension ext)
virtual void giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord=0)
void letNormalBe(const FloatArrayF< 3 > &iN)
Assigns normal vector.
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
GaussPoint IntegrationPoint
Definition gausspoint.h:272
const char * __CharTypeToString(CharType _value)
Definition cltypes.C:338

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