OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
prescribedgradient.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 "prescribedgradient.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 #include "unknownnumberingscheme.h"
51 #include "sparsemtrx.h"
52 #include "sparselinsystemnm.h"
53 #include "assemblercallback.h"
54 #include "mathfem.h"
55 
56 namespace oofem {
57 REGISTER_BoundaryCondition(PrescribedGradient);
58 
59 double PrescribedGradient :: give(Dof *dof, ValueModeType mode, double time)
60 {
61  DofIDItem id = dof->giveDofID();
62  FloatArray *coords = dof->giveDofManager()->giveCoordinates();
63 
64  if ( coords->giveSize() != this->mCenterCoord.giveSize() ) {
66 // OOFEM_ERROR("Size of coordinate system different from center coordinate in b.c.");
67 // printf("Warning: Size of coordinate system different from center coordinate in b.c.\n");
68  }
69 
70  double factor = 0;
71  if ( mode == VM_Total ) {
72  factor = this->giveTimeFunction()->evaluateAtTime(time);
73  } else if ( mode == VM_Velocity ) {
74  factor = this->giveTimeFunction()->evaluateVelocityAtTime(time);
75  } else if ( mode == VM_Acceleration ) {
76  factor = this->giveTimeFunction()->evaluateAccelerationAtTime(time);
77  } else {
78  OOFEM_ERROR("Should not be called for value mode type then total, velocity, or acceleration.");
79  }
80  // Reminder: u_i = d_ij . (x_j - xb_j) = d_ij . dx_j
81  FloatArray dx;
82  dx.beDifferenceOf(* coords, this->mCenterCoord);
83 
84  mGradient.resizeWithData(coords->giveSize(), coords->giveSize());
85 
86  FloatArray u;
87  u.beProductOf(mGradient, dx);
88  u.times( factor );
89 
91  int pos = this->dofs.findFirstIndexOf(id);
92 // printf("pos: %d\n", pos);
93  if(pos > 0 && pos <= u.giveSize()) {
94  return u.at(pos);
95  }
96  else {
97  // XFEM dofs
98  return 0.0;
99  }
100 }
101 
102 
104 // This is written in a very general way, supporting both fm and sm problems.
105 // v_prescribed = C.d = (x-xbar).d;
106 // Modified by ES.
107 // C = [x 0 0 y]
108 // [0 y x 0]
109 // [ ... ] in 2D, voigt form [d_11, d_22, d_12 d_21]
110 // C = [x 0 0 0 z y 0 0 0]
111 // [0 y 0 z 0 0 0 0 x]
112 // [0 0 z 0 0 0 y x 0]
113 // [ ............... ] in 3D, voigt form [d_11, d_22, d_33, d_23, d_13, d_12, d_32, d_31, d_21]
114 {
115  Domain *domain = this->giveDomain();
116 
117  int nsd = domain->giveNumberOfSpatialDimensions();
119  C.resize(npeq, nsd * nsd);
120  C.zero();
121 
122  FloatArray &cCoords = this->giveCenterCoordinate();
123  double xbar = cCoords.at(1), ybar = cCoords.at(2), zbar = 0.0;
124  if ( nsd == 3 ) {
125  zbar = cCoords.at(3);
126  }
127 
128  for ( auto &n : domain->giveDofManagers() ) {
129  FloatArray *coords = n->giveCoordinates();
130  Dof *d1 = n->giveDofWithID( this->dofs(0) );
131  Dof *d2 = n->giveDofWithID( this->dofs(1) );
132  int k1 = d1->__givePrescribedEquationNumber();
133  int k2 = d2->__givePrescribedEquationNumber();
134  if ( nsd == 2 ) {
135  if ( k1 ) {
136  C.at(k1, 1) = coords->at(1) - xbar;
137  C.at(k1, 4) = coords->at(2) - ybar;
138  }
139 
140  if ( k2 ) {
141  C.at(k2, 2) = coords->at(2) - ybar;
142  C.at(k2, 3) = coords->at(1) - xbar;
143  }
144  } else { // nsd == 3
145  Dof *d3 = n->giveDofWithID( this->dofs(2) );
146  int k3 = d3->__givePrescribedEquationNumber();
147 
148  if ( k1 ) {
149  C.at(k1, 1) = coords->at(1) - xbar;
150  C.at(k1, 6) = coords->at(2) - ybar;
151  C.at(k1, 5) = coords->at(3) - zbar;
152  }
153  if ( k2 ) {
154  C.at(k2, 2) = coords->at(2) - ybar;
155  C.at(k2, 9) = coords->at(1) - xbar;
156  C.at(k2, 4) = coords->at(3) - zbar;
157  }
158  if ( k3 ) {
159  C.at(k3, 3) = coords->at(3) - zbar;
160  C.at(k3, 8) = coords->at(1) - xbar;
161  C.at(k3, 7) = coords->at(2) - ybar;
162  }
163  }
164  }
165 }
166 
167 
169 {
170  EngngModel *emodel = this->domain->giveEngngModel();
172  FloatArray R_c(npeq), R_ext(npeq);
173 
174  R_c.zero();
175  R_ext.zero();
176  emodel->assembleVector( R_c, tStep, InternalForceAssembler(), VM_Total,
178  emodel->assembleVector( R_ext, tStep, ExternalForceAssembler(), VM_Total,
180  R_c.subtract(R_ext);
181 
182  // Condense it;
183  FloatMatrix C;
184  this->updateCoefficientMatrix(C);
185  sigma.beTProductOf(C, R_c);
186  sigma.times( 1. / this->domainSize(this->giveDomain(), this->giveSetNumber()) );
187 }
188 
189 
191 // a = [a_c; a_f];
192 // K.a = [R_c,0];
193 // [K_cc, K_cf; K_fc, K_ff].[a_c;a_f] = [R_c; 0];
194 // a_c = d.[x-x_b] = [x-x_b].d = C.d
195 // E = C'.(K_cc - K_cf.K_ff^(-1).K_fc).C
196 // = C'.(K_cc.C - K_cf.(K_ff^(-1).(K_fc.C)))
197 // = C'.(K_cc.C - K_cf.a)
198 // = C'.X
199 {
200  // Fetch some information from the engineering model
201  EngngModel *rve = this->giveDomain()->giveEngngModel();
203  std :: unique_ptr< SparseLinearSystemNM >solver( classFactory.createSparseLinSolver( ST_Petsc, this->domain, this->domain->giveEngngModel() ) ); // = rve->giveLinearSolver();
204  SparseMtrxType stype = solver->giveRecommendedMatrix(true);
207 
208  // Set up and assemble tangent FE-matrix which will make up the sensitivity analysis for the macroscopic material tangent.
209  std :: unique_ptr< SparseMtrx >Kff( classFactory.createSparseMtrx(stype) );
210  std :: unique_ptr< SparseMtrx >Kfp( classFactory.createSparseMtrx(stype) );
211  std :: unique_ptr< SparseMtrx >Kpf( classFactory.createSparseMtrx(stype) );
212  std :: unique_ptr< SparseMtrx >Kpp( classFactory.createSparseMtrx(stype) );
213  if ( !Kff ) {
214  OOFEM_ERROR("Couldn't create sparse matrix of type %d\n", stype);
215  }
216  Kff->buildInternalStructure(rve, 1, fnum);
217  Kfp->buildInternalStructure(rve, 1, fnum, pnum);
218  Kpf->buildInternalStructure(rve, 1, pnum, fnum);
219  Kpp->buildInternalStructure(rve, 1, pnum);
220  rve->assemble(*Kff, tStep, TangentAssembler(TangentStiffness), fnum, this->domain);
221  rve->assemble(*Kfp, tStep, TangentAssembler(TangentStiffness), fnum, pnum, this->domain);
222  rve->assemble(*Kpf, tStep, TangentAssembler(TangentStiffness), pnum, fnum, this->domain);
223  rve->assemble(*Kpp, tStep, TangentAssembler(TangentStiffness), pnum, this->domain);
224 
225  FloatMatrix C, X, Kpfa, KfpC, a;
226 
227  this->updateCoefficientMatrix(C);
228  Kpf->timesT(C, KfpC);
229  solver->solve(*Kff, KfpC, a);
230  Kpp->times(C, X);
231  Kpf->times(a, Kpfa);
232  X.subtract(Kpfa);
233  tangent.beTProductOf(C, X);
234  tangent.times( 1. / this->domainSize(this->giveDomain(), this->giveSetNumber()) );
235 }
236 
237 
239 {
242 }
243 
244 
246 {
249 }
250 } // end namespace oofem
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
virtual void giveInputRecord(DynamicInputRecord &input)
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition: femcmpnn.h:82
SparseMtrx * createSparseMtrx(SparseMtrxType type)
Creates new instance of sparse matrix corresponding to given keyword.
Definition: classfactory.C:105
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 FloatArray * giveCoordinates()
Definition: dofmanager.h:382
EngngModel * giveEngngModel()
Returns engineering model to which receiver is associated.
Definition: domain.C:433
Implementation for assembling tangent matrices in standard monolithic FE-problems.
std::vector< std::unique_ptr< DofManager > > & giveDofManagers()
Definition: domain.h:400
int giveNumber()
Returns domain number.
Definition: domain.h:266
int giveNumberOfSpatialDimensions()
Returns number of spatial dimensions.
Definition: domain.C:1067
virtual int __givePrescribedEquationNumber()=0
Returns prescribed equation number of receiver.
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Sets receiver to be a - b.
Definition: floatarray.C:341
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
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
int giveSetNumber()
Gives the set number which boundary condition is applied to.
#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.
Implementation for assembling external forces vectors in standard monolithic FE-problems.
void resizeWithData(int, int)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1369
void times(double f)
Multiplies receiver by factor f.
Definition: floatmatrix.C:1594
FloatArray & giveCenterCoordinate()
Returns the center coordinate.
DofIDItem giveDofID() const
Returns DofID value of receiver, which determines type of of unknown connected to receiver (e...
Definition: dof.h:276
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
IntArray dofs
Dofs that b.c. is applied to (relevant for Dirichlet type b.c.s).
void resizeWithValues(int s, int allocChunk=0)
Checks size of receiver towards requested bounds.
Definition: floatarray.C:615
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 updateCoefficientMatrix(FloatMatrix &C)
Constructs a coefficient matrix for all prescribed unknowns.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
virtual void computeTangent(FloatMatrix &tangent, TimeStep *tStep)
Computes the macroscopic tangent for homogenization problems through sensitivity analysis.
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
virtual void computeField(FloatArray &sigma, TimeStep *tStep)
Computes the homogenized, macroscopic, field (stress).
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
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.
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
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
virtual double give(Dof *dof, ValueModeType mode, double time)
Domain * giveDomain() const
Definition: femcmpnn.h:100
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
DofManager * giveDofManager() const
Definition: dof.h:123
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
the oofem namespace is to define a context or scope in which all oofem names are defined.
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
int findFirstIndexOf(int value) const
Finds index of first occurrence of given value in array.
Definition: intarray.C:331

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