OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
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 - 2013 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 
54 namespace oofem {
55 REGISTER_BoundaryCondition(PrescribedGenStrainShell7);
56 
57 double 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 
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 
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();
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 
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 
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;
226  this->updateCoefficientMatrix(C);
227  sigma.beTProductOf(C, R_c);
228  sigma.times( 1. / this->domainSize() );
229 }
230 
231 
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 
269  this->updateCoefficientMatrix(C);
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 
281 {
282  IRResultType result; // Required by IR_GIVE_FIELD macro
283 
284  IR_GIVE_FIELD(ir, this->gradient, _IFT_PrescribedGenStrainShell7_gradient);
285 
287  this->centerCoord.zero();
289 
291 }
292 
293 
295 {
297  input.setField(this->gradient, _IFT_PrescribedGenStrainShell7_gradient);
299 }
300 } // end namespace oofem
void setField(int item, InputFieldType id)
int giveNumberOfColumns() const
Returns number of columns of receiver.
Definition: floatmatrix.h:158
The representation of EngngModel default unknown numbering.
REGISTER_BoundaryCondition(BoundaryCondition)
virtual double evaluateAccelerationAtTime(double t)=0
Returns the second time derivative of the function at given time.
Class and object Domain.
Definition: domain.h:115
Implementation for assembling internal forces vectors in standard monolithic, nonlinear FE-problems...
virtual int giveNumberOfDomainEquations(int di, const UnknownNumberingScheme &num)
Returns number of equations for given domain in active (current time step) time step.
Definition: engngm.C:391
FloatArray centerCoord
Center coordinate .
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition: femcmpnn.h:82
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
Definition: domain.h:432
SparseMtrx * createSparseMtrx(SparseMtrxType type)
Creates new instance of sparse matrix corresponding to given keyword.
Definition: classfactory.C:105
virtual FloatArray & giveCenterCoordinate()
Returns the center coordinate.
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
EngngModel * giveEngngModel()
Returns engineering model to which receiver is associated.
Definition: domain.C:433
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
Abstract base class for all finite elements.
Definition: element.h:145
int giveNumber()
Returns domain number.
Definition: domain.h:266
virtual double evalNXIntegral(int boundary, const FEICellGeometry &cellgeo)
Computes the integral .
Definition: feinterpol.h:420
int giveNumberOfSpatialDimensions()
Returns number of spatial dimensions.
Definition: domain.C:1067
void computeField(FloatArray &sigma, EquationID eid, TimeStep *tStep)
Computes the homogenized, macroscopic, field (stress).
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
virtual int __givePrescribedEquationNumber()=0
Returns prescribed equation number of receiver.
virtual FEInterpolation * giveInterpolation() const
Definition: element.h:629
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Class representing a general abstraction for finite element interpolation class.
Definition: feinterpol.h:132
virtual void assemble(SparseMtrx &answer, TimeStep *tStep, const MatrixAssembler &ma, const UnknownNumberingScheme &s, Domain *domain)
Assembles characteristic matrix of required type into given sparse matrix.
Definition: engngm.C:803
Element * giveElement(int n)
Service for accessing particular domain fe element.
Definition: domain.C:160
#define OOFEM_ERROR(...)
Definition: error.h:61
DofIDItem
Type representing particular dof type.
Definition: dofiditem.h:86
SparseMtrxType
Enumerative type used to identify the sparse matrix type.
virtual void setPrescribedGenStrainShell7Voigt(const FloatArray &t)
Sets the prescribed tensor from the matrix from given voigt notation.
Implementation for assembling external forces vectors in standard monolithic FE-problems.
void computeTangent(FloatMatrix &tangent, EquationID eid, TimeStep *tStep)
Computes the macroscopic tangent for homogenization problems through sensitivity analysis.
void times(double f)
Multiplies receiver by factor f.
Definition: floatmatrix.C:1594
Set of elements, boundaries, edges and/or nodes.
Definition: set.h:66
Wrapper around element definition to provide FEICellGeometry interface.
Definition: feinterpol.h:95
Set * giveSet(int n)
Service for accessing particular domain set.
Definition: domain.C:363
IntArray dofs
Dofs that b.c. is applied to (relevant for Dirichlet type b.c.s).
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix^T and anArray.
Definition: floatarray.C:708
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
void subtract(const FloatMatrix &a)
Subtracts matrix from the receiver.
Definition: floatmatrix.C:1084
virtual double evaluateVelocityAtTime(double t)=0
Returns the first time derivative of the function at given time.
Class representing vector of real numbers.
Definition: floatarray.h:82
SparseLinearSystemNM * createSparseLinSolver(LinSystSolverType st, Domain *d, EngngModel *m)
Creates new instance of SparseLinearSystemNM corresponding to given type.
Definition: classfactory.C:120
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
void updateCoefficientMatrix(FloatMatrix &C)
Constructs a coefficient matrix for all prescribed unknowns.
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
Class representing the general Input Record.
Definition: inputrecord.h:101
The representation of EngngModel default prescribed unknown numbering.
Dof * giveDofWithID(int dofID) const
Returns DOF with given dofID; issues error if not present.
Definition: dofmanager.C:119
FloatMatrix gradient
Prescribed gradient .
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:367
Class representing the a dynamic Input Record.
void times(double s)
Multiplies receiver with scalar.
Definition: floatarray.C:818
ClassFactory & classFactory
Definition: classfactory.C:59
virtual FloatArray * giveCoordinates()
Definition: node.h:114
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
Domain * giveDomain() const
Definition: femcmpnn.h:100
#define _IFT_PrescribedGenStrainShell7_centercoords
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
Node * giveNode(int n)
Service for accessing particular domain node.
Definition: domain.h:371
the oofem namespace is to define a context or scope in which all oofem names are defined.
Class implementing node in finite element mesh.
Definition: node.h:87
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
Abstract class Dof represents Degree Of Freedom in finite element mesh.
Definition: dof.h:93
int giveNumber() const
Definition: femcmpnn.h:107
virtual double evaluateAtTime(double t)
Returns the value of the function at given time.
Definition: function.C:76
void assembleVector(FloatArray &answer, TimeStep *tStep, const VectorAssembler &va, ValueModeType mode, const UnknownNumberingScheme &s, Domain *domain, FloatArray *eNorms=NULL)
Assembles characteristic vector of required type from dofManagers, element, and active boundary condi...
Definition: engngm.C:986
Class representing solution step.
Definition: timestep.h:80
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
virtual double give(Dof *dof, ValueModeType mode, double time)
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:30 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011