OOFEM 3.0
Loading...
Searching...
No Matches
prescribedgradientshell7base.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
35#include "PrescribedGenStrainShell7shell7base.h"
36#include "dofiditem.h"
37#include "dofmanager.h"
38#include "dof.h"
39#include "valuemodetype.h"
40#include "floatarray.h"
41#include "floatmatrix.h"
42#include "function.h"
43#include "engngm.h"
44#include "set.h"
45#include "node.h"
46#include "element.h"
47#include "classfactory.h"
48#include "dynamicinputrecord.h"
49#include "feinterpol.h"
50
51#include "sparsemtrx.h"
52#include "sparselinsystemnm.h"
53
54namespace oofem {
56
57double PrescribedGenStrainShell7 :: give(Dof *dof, ValueModeType mode, double time)
58{
59 DofIDItem id = dof->giveDofID();
60 FloatArray *coords = dof->giveDofManager()->giveCoordinates();
61
62 if ( coords->giveSize() != this->centerCoord.giveSize() ) {
63 OOFEM_ERROR("PrescribedGenStrainShell7 :: give - Size of coordinate system different from center coordinate in b.c.");
64 }
65
66 double factor = 0;
67 if ( mode == VM_Total ) {
68 factor = this->giveTimeFunction()->evaluateAtTime(time);
69 } else if ( mode == VM_Velocity ) {
70 factor = this->giveTimeFunction()->evaluateVelocityAtTime(time);
71 } else if ( mode == VM_Acceleration ) {
72 factor = this->giveTimeFunction()->evaluateAccelerationAtTime(time);
73 } else {
74 OOFEM_ERROR("Should not be called for value mode type then total, velocity, or acceleration.");
75 }
76
77 // Reminder: u_i = F_ij . (x_j - xb_j) = d_ij . dx_j
78 FloatArray dx;
79 dx.beDifferenceOf(* coords, this->centerCoord);
80
81 FloatArray u;
82 u.beProductOf(gradient, dx);
83 u.times( factor );
84
85 switch ( id ) {
86 case D_u:
87 case V_u:
88 return u.at(1);
89
90 case D_v:
91 case V_v:
92 return u.at(2);
93
94 case D_w:
95 case V_w:
96 return u.at(3);
97
98 default:
99 return 0.0;
100 }
101}
102
103void PrescribedGenStrainShell7 :: setPrescribedGenStrainShell7Voigt(const FloatArray &t)
104{
105 int n = t.giveSize();
106 if ( n == 3 ) { // Then 2D
107 this->gradient.resize(2, 2);
108 this->gradient.at(1, 1) = t.at(1);
109 this->gradient.at(2, 2) = t.at(2);
110 this->gradient.at(1, 2) = this->gradient.at(2, 1) = t.at(3);
111 } else if ( n == 6 ) { // Then 3D
112 this->gradient.resize(3, 3);
113 this->gradient.at(1, 1) = t.at(1);
114 this->gradient.at(2, 2) = t.at(2);
115 this->gradient.at(3, 3) = t.at(3);
116 // In voigt form, assuming the use of gamma_12 instead of eps_12
117 this->gradient.at(1, 2) = this->gradient.at(2, 1) = t.at(6) * 0.5;
118 this->gradient.at(1, 3) = this->gradient.at(3, 1) = t.at(5) * 0.5;
119 this->gradient.at(2, 3) = this->gradient.at(3, 2) = t.at(4) * 0.5;
120 } else {
121 OOFEM_ERROR("setPrescribedTensorVoigt: Tensor is in strange voigt format. Should be 3 or 6. Use setPrescribedTensor directly if needed.");
122 }
123}
124
125void PrescribedGenStrainShell7 :: updateCoefficientMatrix(FloatMatrix &C)
126// This is written in a very general way, supporting both fm and sm problems.
127// v_prescribed = C.d = (x-xbar).d;
128// C = [x 0 y]
129// [0 y x]
130// [ ... ] in 2D, voigt form [d_11, d_22, d_12]
131// C = [x 0 0 y z 0]
132// [0 y 0 x 0 z]
133// [0 0 z 0 x y]
134// [ ......... ] in 3D, voigt form [d_11, d_22, d_33, d_23, d_13, d_12]
135{
136 Domain *domain = this->giveDomain();
137 int nNodes = domain->giveNumberOfDofManagers();
138
139 int nsd = domain->giveNumberOfSpatialDimensions();
140 int npeq = domain->giveEngngModel()->giveNumberOfDomainEquations( domain->giveNumber(), EModelDefaultPrescribedEquationNumbering() );
141 C.resize(npeq, nsd * ( nsd + 1 ) / 2);
142 C.zero();
143
144 FloatArray &cCoords = this->giveCenterCoordinate();
145 double xbar = cCoords.at(1), ybar = cCoords.at(2), zbar = 0.0;
146 if ( nsd == 3 ) {
147 zbar = cCoords.at(3);
148 }
149
150 for ( int i = 1; i <= nNodes; i++ ) {
151 Node *n = domain->giveNode(i);
152 FloatArray *coords = n->giveCoordinates();
153 Dof *d1 = n->giveDofWithID( this->dofs[0] );
154 Dof *d2 = n->giveDofWithID( this->dofs[1] );
155 int k1 = d1->__givePrescribedEquationNumber();
156 int k2 = d2->__givePrescribedEquationNumber();
157 if ( nsd == 2 ) {
158 if ( k1 ) {
159 C.at(k1, 1) = coords->at(1) - xbar;
160 C.at(k1, 3) = coords->at(2) - ybar;
161 }
162
163 if ( k2 ) {
164 C.at(k2, 2) = coords->at(2) - ybar;
165 C.at(k2, 3) = coords->at(1) - xbar;
166 }
167 } else { // nsd == 3
168 OOFEM_ERROR("PrescribedGenStrainShell7 :: updateCoefficientMatrix - 3D Not tested yet!");
169 Dof *d3 = n->giveDofWithID( this->dofs(2) );
170 int k3 = d3->__givePrescribedEquationNumber();
171
172 if ( k1 ) {
173 C.at(k1, 1) = coords->at(1) - xbar;
174 C.at(k1, 4) = coords->at(2) - ybar;
175 C.at(k1, 5) = coords->at(3) - zbar;
176 }
177 if ( k2 ) {
178 C.at(k2, 2) = coords->at(2) - ybar;
179 C.at(k2, 4) = coords->at(1) - xbar;
180 C.at(k2, 6) = coords->at(3) - zbar;
181 }
182 if ( k3 ) {
183 C.at(k3, 3) = coords->at(3) - zbar;
184 C.at(k3, 5) = coords->at(1) - xbar;
185 C.at(k3, 6) = coords->at(2) - ybar;
186 }
187 }
188 }
189}
190
191
192double PrescribedGenStrainShell7 :: domainSize()
193{
194 int nsd = this->domain->giveNumberOfSpatialDimensions();
195 double domain_size = 0.0;
196 // This requires the boundary to be consistent and ordered correctly.
197 Set *set = this->giveDomain()->giveSet(this->set);
198 const IntArray &boundaries = set->giveBoundaryList();
199
200 for ( int pos = 1; pos <= boundaries.giveSize() / 2; ++pos ) {
201 Element *e = this->giveDomain()->giveElement( boundaries.at(pos * 2 - 1) );
202 int boundary = boundaries.at(pos * 2);
204 domain_size += fei->evalNXIntegral( boundary, FEIElementGeometryWrapper(e) );
205 }
206 return domain_size / nsd;
207}
208
209
210void PrescribedGenStrainShell7 :: computeField(FloatArray &sigma, EquationID eid, TimeStep *tStep)
211{
212 EngngModel *emodel = this->domain->giveEngngModel();
214 FloatArray R_c(npeq), R_ext(npeq);
215
216 R_c.zero();
217 R_ext.zero();
218 emodel->assembleVector( R_c, tStep, eid, InternalForceAssembler(), VM_Total,
220 emodel->assembleVector( R_ext, tStep, eid, ExternalForceAssembler(), VM_Total,
222 R_c.subtract(R_ext);
223
224 // Condense it;
225 FloatMatrix C;
227 sigma.beTProductOf(C, R_c);
228 sigma.times( 1. / this->domainSize() );
229}
230
231
232void PrescribedGenStrainShell7 :: computeTangent(FloatMatrix &tangent, EquationID eid, TimeStep *tStep)
233// a = [a_c; a_f];
234// K.a = [R_c,0];
235// [K_cc, K_cf; K_fc, K_ff].[a_c;a_f] = [R_c; 0];
236// a_c = d.[x-x_b] = [x-x_b].d = C.d
237// E = C'.(K_cc - K_cf.K_ff^(-1).K_fc).C
238// = C'.(K_cc.C - K_cf.(K_ff^(-1).(K_fc.C)))
239// = C'.(K_cc.C - K_cf.a)
240// = C'.X
241{
242 // Fetch some information from the engineering model
243 EngngModel *rve = this->giveDomain()->giveEngngModel();
245 std :: unique_ptr< SparseLinearSystemNM > solver( classFactory.createSparseLinSolver( ST_Petsc, this->domain, this->domain->giveEngngModel() ) ); // = rve->giveLinearSolver();
246 SparseMtrxType stype = solver->giveRecommendedMatrix(true);
249
250 // Set up and assemble tangent FE-matrix which will make up the sensitivity analysis for the macroscopic material tangent.
251 std :: unique_ptr< SparseMtrx > Kff( classFactory.createSparseMtrx(stype) );
252 std :: unique_ptr< SparseMtrx > Kfp( classFactory.createSparseMtrx(stype) );
253 std :: unique_ptr< SparseMtrx > Kpf( classFactory.createSparseMtrx(stype) );
254 std :: unique_ptr< SparseMtrx > Kpp( classFactory.createSparseMtrx(stype) );
255 if ( !Kff ) {
256 OOFEM_ERROR("MixedGradientPressureBC :: computeTangents - Couldn't create sparse matrix of type %d\n", stype);
257 }
258 Kff->buildInternalStructure(rve, 1, eid, fnum);
259 Kfp->buildInternalStructure(rve, 1, eid, fnum, pnum);
260 Kpf->buildInternalStructure(rve, 1, eid, pnum, fnum);
261 Kpp->buildInternalStructure(rve, 1, eid, pnum);
262 rve->assemble(*Kff, tStep, eid, TangentStiffnessMatrix, fnum, this->domain);
263 rve->assemble(*Kfp, tStep, eid, TangentStiffnessMatrix, fnum, pnum, this->domain);
264 rve->assemble(*Kpf, tStep, eid, TangentStiffnessMatrix, pnum, fnum, this->domain);
265 rve->assemble(*Kpp, tStep, eid, TangentStiffnessMatrix, pnum, this->domain);
266
267 FloatMatrix C, X, Kpfa, KfpC, a;
268
270 Kpf->timesT(C, KfpC);
271 solver->solve(*Kff, KfpC, a);
272 Kpp->times(C, X);
273 Kpf->times(a, Kpfa);
274 X.subtract(Kpfa);
275 tangent.beTProductOf(C, X);
276 tangent.times( 1. / this->domainSize() );
277}
278
279
280void PrescribedGenStrainShell7 :: initializeFrom(InputRecord &ir)
281{
282 GeneralBoundaryCondition :: initializeFrom(ir);
283
284 IR_GIVE_FIELD(ir, this->gradient, _IFT_PrescribedGenStrainShell7_gradient);
285
286 this->centerCoord.resize( this->gradient.giveNumberOfColumns() );
287 this->centerCoord.zero();
289}
290
291
292void PrescribedGenStrainShell7 :: giveInputRecord(DynamicInputRecord &input)
293{
294 BoundaryCondition :: giveInputRecord(input);
295 input.setField(this->gradient, _IFT_PrescribedGenStrainShell7_gradient);
296 input.setField(this->centerCoord, _IFT_PrescribedGenStrainShell7_centercoords);
297}
298} // end namespace oofem
#define REGISTER_BoundaryCondition(class)
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
Dof * giveDofWithID(int dofID) const
Definition dofmanager.C:127
virtual int __givePrescribedEquationNumber()=0
virtual FEInterpolation * giveInterpolation() const
Definition element.h:648
virtual int giveNumberOfDomainEquations(int di, const UnknownNumberingScheme &num)
Definition engngm.C:452
virtual void assemble(SparseMtrx &answer, TimeStep *tStep, const MatrixAssembler &ma, const UnknownNumberingScheme &s, Domain *domain)
Definition engngm.C:889
void assembleVector(FloatArray &answer, TimeStep *tStep, const VectorAssembler &va, ValueModeType mode, const UnknownNumberingScheme &s, Domain *domain, FloatArray *eNorms=NULL)
Definition engngm.C:1106
virtual double evalNXIntegral(int boundary, const FEICellGeometry &cellgeo) const
Definition feinterpol.h:477
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 giveNumber() const
Definition femcmpnn.h:104
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Definition floatarray.C:403
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:721
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
void subtract(const FloatMatrix &a)
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
IntArray dofs
Dofs that b.c. is applied to (relevant for Dirichlet type b.c.s).
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
FloatMatrixF< 3, 3 > gradient
Prescribed gradient .
virtual FloatArrayF< 3 > & giveCenterCoordinate()
Returns the center coordinate.
const IntArray & giveBoundaryList()
Definition set.C:160
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
ClassFactory & classFactory
#define _IFT_PrescribedGenStrainShell7_centercoords

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