OOFEM 3.0
Loading...
Searching...
No Matches
lattice2d_mt.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 "domain.h"
47#include "mathfem.h"
48#include "engngm.h"
49#include "load.h"
50#include "classfactory.h"
51#include "parametermanager.h"
52#include "paramkey.h"
53
54#ifdef __OOFEG
55 #include "oofeggraphiccontext.h"
56 #include "connectivitytable.h"
57#endif
58
59namespace oofem {
61
69
70Lattice2d_mt :: Lattice2d_mt(int n, Domain *aDomain, ElementMode em) :
71 LatticeTransportElement(n, aDomain, em)
72{
74 dimension = 2.;
76 couplingNumbers.resize(1);
77 couplingNumbers.zero();
78 crackWidths.resize(1);
79 crackWidths.zero();
80}
81
82double Lattice2d_mt :: giveLength()
83{
84 if ( length == 0. ) {
85 Node *nodeA = this->giveNode(1);
86 Node *nodeB = this->giveNode(2);
87 double dx = nodeB->giveCoordinate(1) - nodeA->giveCoordinate(1);
88 double dy = nodeB->giveCoordinate(2) - nodeA->giveCoordinate(2);
89 length = sqrt(dx * dx + dy * dy);
90 }
91
92 return length;
93}
94
95double
96Lattice2d_mt :: givePressure()
97{
99 GaussPoint *gp = iRule->getIntegrationPoint(0);
100 auto status = static_cast< LatticeTransportMaterialStatus * >( gp->giveMaterialStatus() );
101
102 return status->givePressure();
103}
104
105double
106Lattice2d_mt :: giveOldPressure()
107{
109 GaussPoint *gp = iRule->getIntegrationPoint(0);
110 auto status = static_cast< LatticeTransportMaterialStatus * >( gp->giveMaterialStatus() );
111
112 return status->giveOldPressure();
113}
114
115
116double
117Lattice2d_mt :: giveMass()
118{
120 GaussPoint *gp = iRule->getIntegrationPoint(0);
121 auto status = static_cast< LatticeTransportMaterialStatus * >( gp->giveMaterialStatus() );
122
123 double mass = status->giveMass();
124 //multiply with volume
125 mass *= this->length * this->width / 2.;
126 return mass;
127}
128
129
130void
131Lattice2d_mt :: computeNSubMatrixAt(FloatMatrix &answer, const FloatArray &coords)
132{
133 double ksi = coords.at(1);
134 double n1 = ( 1. - ksi ) * 0.5;
135 double n2 = ( 1. + ksi ) * 0.5;
136
137 answer.resize(1, 2);
138 answer.zero();
139
140 answer.at(1, 1) = n1;
141 answer.at(1, 2) = n2;
142}
143
144void
145Lattice2d_mt :: computeNmatrixAt(FloatMatrix &answer, const FloatArray &coords)
146{
147 this->computeNSubMatrixAt(answer, coords);
148}
149
150
151void
152Lattice2d_mt :: computeGradientMatrixAt(FloatMatrix &answer, const FloatArray &lcoords)
153{
154 double l = this->giveLength();
155
156 // Assemble Gradient Matrix used to compute temperature gradient
157 answer.resize(1, 2);
158 answer.zero();
159 answer.at(1, 1) = -1.;
160 answer.at(1, 2) = 1.;
161
162 answer.times(1. / l);
163}
164
165void
166Lattice2d_mt :: updateInternalState(TimeStep *tStep)
167{
168 FloatArray f, r;
169 FloatMatrix n;
170 TransportMaterial *mat = static_cast< TransportMaterial * >( this->giveMaterial() );
171
172 // force updating ip values
173 for ( auto &iRule: integrationRulesArray ) {
174 for ( auto &gp: * iRule ) {
175 this->computeNmatrixAt(n, gp->giveNaturalCoordinates() );
176 this->computeVectorOf({ P_f }, VM_Total, tStep, r);
177 f.beProductOf(n, r);
178 mat->updateInternalState(f, gp, tStep);
179 }
180 }
181}
182
183
184void
185Lattice2d_mt :: computeGaussPoints()
186{
187 integrationRulesArray.resize(1);
188 integrationRulesArray [ 0 ] = std :: make_unique< GaussIntegrationRule >(1, this, 1, 2);
189 integrationRulesArray [ 0 ]->SetUpPointsOnLine(1, _2dMTLattice);
190}
191
192void
193Lattice2d_mt :: giveDofManDofIDMask(int inode, IntArray &answer) const
194{
195 answer = { P_f };
196}
197
198void
199Lattice2d_mt :: initializeFrom(InputRecord &ir, int priority)
200{
201 ParameterManager &ppm = this->giveDomain()->elementPPM;
202
203 // first call parent
204 LatticeTransportElement :: initializeFrom(ir, priority);
205 PM_UPDATE_PARAMETER(dimension, ppm, ir, this->number, IPK_Lattice2d_mt_dim, priority) ;
207 PM_UPDATE_PARAMETER(width, ppm, ir, this->number, IPK_Lattice2d_mt_width, priority) ;
209 PM_UPDATE_PARAMETER(crackWidths.at(1), ppm, ir, this->number, IPK_Lattice2d_mt_crackwidth, priority) ;
211 PM_UPDATE_PARAMETER(couplingNumbers.at(1), ppm, ir, this->number, IPK_Lattice2d_mt_couplingnumber, priority) ;
212}
213
214void
215Lattice2d_mt :: postInitialize()
216{
217 ParameterManager &ppm = this->giveDomain()->elementPPM;
218 this->LatticeTransportElement :: postInitialize();
219
223 crackLengths.resize(1);
224 crackLengths.at(1) = width;
226}
227
228double
229Lattice2d_mt :: computeVolumeAround(GaussPoint *gp)
230{
231 return this->width * this->thickness * this->giveLength();
232}
233
234void
235Lattice2d_mt :: computeConductivityMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
236{
237 std :: unique_ptr< IntegrationRule > &iRule = integrationRulesArray [ 0 ];
238 GaussPoint *gp = iRule->getIntegrationPoint(0);
239
240 answer.resize(2, 2);
241 answer.zero();
242 answer.at(1, 1) = 1.;
243 answer.at(1, 2) = -1.;
244 answer.at(2, 1) = -1;
245 answer.at(2, 2) = 1.;
246
247 double k = static_cast< TransportMaterial * >( this->giveMaterial() )->giveCharacteristicValue(Conductivity, gp, tStep);
248 double dV = this->computeVolumeAround(gp);
249 double length = giveLength();
250 double temp = k * dV / pow(length, 2.);
251 answer.times(temp);
252}
253
254
255void
256Lattice2d_mt :: computeCapacityMatrix(FloatMatrix &answer, TimeStep *tStep)
257{
258 GaussPoint *gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
259 answer.resize(2, 2);
260 answer.zero();
261 answer.at(1, 1) = 2.;
262 answer.at(1, 2) = 1.;
263 answer.at(2, 1) = 1.;
264 answer.at(2, 2) = 2.;
265 double c = static_cast< TransportMaterial * >( this->giveMaterial() )->giveCharacteristicValue(Capacity, gp, tStep);
266 double dV = this->computeVolumeAround(gp) / ( 6.0 * this->dimension );
267 answer.times(c * dV);
268}
269
270
271
272void
273Lattice2d_mt :: computeInternalSourceRhsVectorAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
274{
275 std :: unique_ptr< IntegrationRule > &iRule = integrationRulesArray [ 0 ];
276
277 FloatArray deltaX(3);
278 FloatArray val, helpLoadVector, globalIPcoords;
279 FloatMatrix nm;
280 answer.clear();
281
282 FloatArray gravityHelp(2);
283
284 int nLoads = this->giveBodyLoadArray()->giveSize();
285 for ( int i = 1; i <= nLoads; i++ ) {
286 int n = bodyLoadArray.at(i);
287 auto load = domain->giveLoad(n);
288 auto ltype = load->giveBCGeoType();
289
290 if ( ltype == GravityPressureBGT ) {
291 //Compute change of coordinates
292 Node *nodeA = this->giveNode(1);
293 Node *nodeB = this->giveNode(2);
294 deltaX.at(1) = nodeB->giveCoordinate(1) - nodeA->giveCoordinate(1);
295 deltaX.at(2) = nodeB->giveCoordinate(2) - nodeA->giveCoordinate(2);
296 deltaX.at(3) = nodeB->giveCoordinate(2) - nodeA->giveCoordinate(2);
297
298 //Compute the local coordinate system
299 GaussPoint *gp = iRule->getIntegrationPoint(0);
300
301 gravityHelp.at(1) = 1.;
302 gravityHelp.at(2) = -1.;
303
304 double dV = this->computeVolumeAround(gp);
305 load->computeValueAt(val, tStep, deltaX, mode);
306
307 double k = static_cast< TransportMaterial * >( this->giveMaterial() )->giveCharacteristicValue(Conductivity, gp, tStep);
308
309 double helpFactor = val.at(1) * k * dV;
310
311 helpFactor /= pow(this->giveLength(), 2.);
312 gravityHelp.times(helpFactor);
313
314 if ( helpLoadVector.isEmpty() ) {
315 helpLoadVector.resize(gravityHelp.giveSize() );
316 }
317
318 for ( int j = 1; j <= gravityHelp.giveSize(); j++ ) {
319 helpLoadVector.at(j) += gravityHelp.at(j);
320 }
321 }
322
323 answer.add(helpLoadVector);
324 }
325}
326
327
328void
329Lattice2d_mt :: giveGpCoordinates(FloatArray &answer)
330{
331 answer.resize(3);
332 answer.at(1) = this->gpCoords.at(1);
333 answer.at(2) = this->gpCoords.at(2);
334}
335
336int
337Lattice2d_mt :: computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
338{
339 answer.resize(3);
340 answer.at(1) = this->gpCoords.at(1);
341 answer.at(2) = this->gpCoords.at(2);
342
343 return 1;
344}
345
346#define POINT_TOL 1.e-3
347
348bool
349Lattice2d_mt :: computeLocalCoordinates(FloatArray &answer, const FloatArray &coords)
350{
351 answer.resize(1);
352 answer.at(1) = 0.;
353
354 return true;
355}
356
357
358#ifdef __OOFEG
359
360
361void
362Lattice2d_mt :: drawYourself(oofegGraphicContext &gc, TimeStep *tStep)
363{
364 OGC_PlotModeType mode = gc.giveIntVarPlotMode();
365
366 if ( mode == OGC_rawGeometry ) {
367 this->drawRawGeometry(gc, tStep);
368 this->drawRawCrossSections(gc, tStep);
369 } else {
370 OOFEM_ERROR("unsupported mode");
371 }
372}
373
374
375
376
377void Lattice2d_mt :: drawRawGeometry(oofegGraphicContext &gc, TimeStep *tStep)
378{
379 GraphicObj *go;
380 // if (!go) { // create new one
381 WCRec p [ 2 ]; /* poin */
382 if ( !gc.testElementGraphicActivity(this) ) {
383 return;
384 }
385
386 EASValsSetLineWidth(OOFEG_RAW_GEOMETRY_WIDTH);
387 EASValsSetColor(gc.getElementColor() );
388 EASValsSetLayer(OOFEG_RAW_GEOMETRY_LAYER);
389 p [ 0 ].x = ( FPNum ) this->giveNode(1)->giveCoordinate(1);
390 p [ 0 ].y = ( FPNum ) this->giveNode(1)->giveCoordinate(2);
391 p [ 0 ].z = 0.;
392 p [ 1 ].x = ( FPNum ) this->giveNode(2)->giveCoordinate(1);
393 p [ 1 ].y = ( FPNum ) this->giveNode(2)->giveCoordinate(2);
394 p [ 1 ].z = 0.;
395
396 go = CreateLine3D(p);
397 EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | LAYER_MASK, go);
398 EGAttachObject(go, ( EObjectP ) this);
399 EMAddGraphicsToModel(ESIModel(), go);
400}
401
402void Lattice2d_mt :: drawRawCrossSections(oofegGraphicContext &gc, TimeStep *tStep)
403{
404 GraphicObj *go;
405
406 // if (!go) { // create new one
407 WCRec p [ 2 ]; /* poin */
408 if ( !gc.testElementGraphicActivity(this) ) {
409 return;
410 }
411
412 EASValsSetLineWidth(OOFEG_RAW_GEOMETRY_WIDTH);
413 EASValsSetColor(gc.getCrossSectionColor() );
414 EASValsSetLayer(OOFEG_RAW_CROSSSECTION_LAYER);
415
416 FloatArray coords;
417 this->giveCrossSectionCoordinates(coords);
418
419 p [ 0 ].x = ( FPNum ) coords.at(1);
420 p [ 0 ].y = ( FPNum ) coords.at(2);
421 p [ 0 ].z = ( FPNum ) coords.at(3);
422 p [ 1 ].x = ( FPNum ) coords.at(4);
423 p [ 1 ].y = ( FPNum ) coords.at(5);
424 p [ 1 ].z = ( FPNum ) coords.at(6);
425
426 go = CreateLine3D(p);
427 EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | LAYER_MASK, go);
428 EGAttachObject(go, ( EObjectP ) this);
429 EMAddGraphicsToModel(ESIModel(), go);
430}
431
432void
433Lattice2d_mt :: giveCrossSectionCoordinates(FloatArray &coords)
434{
435 double x1 = this->giveNode(1)->giveCoordinate(1);
436 double y1 = this->giveNode(1)->giveCoordinate(2);
437 double x2 = this->giveNode(2)->giveCoordinate(1);
438 double y2 = this->giveNode(2)->giveCoordinate(2);
439
440 //Compute normal and shear direction
441 FloatArray normalDirection(2);
442 FloatArray shearDirection(2);
443
444 normalDirection.at(1) = x2 - x1;
445 normalDirection.at(2) = y2 - y1;
446 normalDirection.normalize();
447 if ( normalDirection.at(2) == 0. ) {
448 shearDirection.at(1) = 0.;
449 shearDirection.at(2) = 1.;
450 } else {
451 shearDirection.at(1) = 1.0;
452 shearDirection.at(2) = -normalDirection.at(1) / normalDirection.at(2);
453 }
454
455 shearDirection.normalize();
456
457 coords.resize(6);
458 coords.at(1) = this->gpCoords.at(1) - shearDirection.at(1) * this->width / 2.;
459 coords.at(2) = this->gpCoords.at(2) - shearDirection.at(2) * this->width / 2.;
460 coords.at(3) = 0.;
461 coords.at(4) = this->gpCoords.at(1) + shearDirection.at(1) * this->width / 2.;
462 coords.at(5) = this->gpCoords.at(2) + shearDirection.at(2) * this->width / 2.;
463 coords.at(6) = 0.;
464}
465
466#endif
467} // end namespace oofem
#define REGISTER_Element(class)
double giveCoordinate(int i) const
Definition dofmanager.h:383
Node * giveNode(int i) const
Definition element.h:629
IntArray * giveBodyLoadArray()
Returns array containing load numbers of loads acting on element.
Definition element.C:411
int numberOfDofMans
Number of dofmanagers.
Definition element.h:136
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Definition element.C:103
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
Definition element.h:157
int numberOfGaussPoints
Definition element.h:175
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Definition element.h:886
virtual double giveCharacteristicValue(CharType type, TimeStep *tStep)
Definition element.C:678
IntArray bodyLoadArray
Definition element.h:147
Domain * giveDomain() const
Definition femcmpnn.h:97
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
int number
Component number.
Definition femcmpnn.h:77
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 beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
bool isEmpty() const
Returns true if receiver is empty.
Definition floatarray.h:265
void add(const FloatArray &src)
Definition floatarray.C:218
void times(double s)
Definition floatarray.C:834
void times(double f)
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
IntegrationPointStatus * giveMaterialStatus(IntegrationPointStatusIDType key=IPSID_Default)
Definition gausspoint.h:204
GaussPoint * getIntegrationPoint(int n)
void drawRawCrossSections(oofegGraphicContext &gc, TimeStep *tStep)
void drawRawGeometry(oofegGraphicContext &gc, TimeStep *tStep) override
static ParamKey IPK_Lattice2d_mt_thickness
static ParamKey IPK_Lattice2d_mt_width
void computeNmatrixAt(FloatMatrix &n, const FloatArray &) override
FloatArray crackLengths
static ParamKey IPK_Lattice2d_mt_crackwidth
static ParamKey IPK_Lattice2d_mt_couplingnumber
void giveCrossSectionCoordinates(FloatArray &coords) override
double computeVolumeAround(GaussPoint *) override
static ParamKey IPK_Lattice2d_mt_dim
static ParamKey IPK_Lattice2d_mt_gpcoords
void computeNSubMatrixAt(FloatMatrix &n, const FloatArray &)
static ParamKey IPK_Lattice2d_mt_couplingflag
FloatArray crackWidths
double giveLength() override
LatticeTransportElement(int, Domain *, ElementMode)
double giveMass() const
Returns mass.
double givePressure() const
Returns pressure.
Material * giveMaterial() override
virtual void updateInternalState(const FloatArray &state, GaussPoint *gp, TimeStep *tStep)
#define OOFEM_ERROR(...)
Definition error.h:79
@ GravityPressureBGT
Pressure due to distributed body load.
Definition bcgeomtype.h:47
#define OOFEG_RAW_CROSSSECTION_LAYER
oofem::oofegGraphicContext gc[OOFEG_LAST_LAYER]
#define OOFEG_RAW_GEOMETRY_WIDTH
#define OOFEG_RAW_GEOMETRY_LAYER
#define PM_ELEMENT_ERROR_IFNOTSET(_pm, _componentnum, _paramkey)
#define PM_UPDATE_PARAMETER(_val, _pm, _ir, _componentnum, _paramkey, _prio)

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