OOFEM 3.0
Loading...
Searching...
No Matches
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 - 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 "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"
51#include "sparsemtrx.h"
52#include "sparselinsystemnm.h"
53#include "assemblercallback.h"
54#include "mathfem.h"
55
56namespace oofem {
58
59double PrescribedGradient :: give(Dof *dof, ValueModeType mode, double time)
60{
61 DofIDItem id = dof->giveDofID();
62 const auto &coords = dof->giveDofManager()->giveCoordinates();
63
64 double factor = 0;
65 if ( mode == VM_Total ) {
66 factor = this->giveTimeFunction()->evaluateAtTime(time);
67 } else if ( mode == VM_Velocity ) {
68 factor = this->giveTimeFunction()->evaluateVelocityAtTime(time);
69 } else if ( mode == VM_Acceleration ) {
70 factor = this->giveTimeFunction()->evaluateAccelerationAtTime(time);
71 } else {
72 OOFEM_ERROR("Should not be called for value mode type then total, velocity, or acceleration.");
73 }
74 // Reminder: u_i = d_ij . (x_j - xb_j) = d_ij . dx_j
75 FloatArray dx;
76 dx.beDifferenceOf(coords, this->mCenterCoord);
77
78 mGradient.resizeWithData(coords.giveSize(), coords.giveSize());
79
80 FloatArray u;
82 u.times( factor );
83
85 int pos = this->dofs.findFirstIndexOf(id);
86// printf("pos: %d\n", pos);
87 if ( pos > 0 && pos <= u.giveSize() ) {
88 return u.at(pos);
89 } else {
90 // XFEM dofs
91 return 0.0;
92 }
93}
94
95
96void PrescribedGradient :: updateCoefficientMatrix(FloatMatrix &C)
97// This is written in a very general way, supporting both fm and sm problems.
98// v_prescribed = C.d = (x-xbar).d;
99// Modified by ES.
100// C = [x 0 0 y]
101// [0 y x 0]
102// [ ... ] in 2D, voigt form [d_11, d_22, d_12 d_21]
103// C = [x 0 0 0 z y 0 0 0]
104// [0 y 0 z 0 0 0 0 x]
105// [0 0 z 0 0 0 y x 0]
106// [ ............... ] in 3D, voigt form [d_11, d_22, d_33, d_23, d_13, d_12, d_32, d_31, d_21]
107{
108 Domain *domain = this->giveDomain();
109
110 int nsd = domain->giveNumberOfSpatialDimensions();
111 int npeq = domain->giveEngngModel()->giveNumberOfDomainEquations( domain->giveNumber(), EModelDefaultPrescribedEquationNumbering() );
112 C.resize(npeq, nsd * nsd);
113 C.zero();
114
115 FloatArray &cCoords = this->giveCenterCoordinate();
116 double xbar = cCoords.at(1), ybar = cCoords.at(2), zbar = 0.0;
117 if ( nsd == 3 ) {
118 zbar = cCoords.at(3);
119 }
120
121 for ( auto &n : domain->giveDofManagers() ) {
122 const auto &coords = n->giveCoordinates();
123 Dof *d1 = n->giveDofWithID( this->dofs[0] );
124 Dof *d2 = n->giveDofWithID( this->dofs[1] );
125 int k1 = d1->__givePrescribedEquationNumber();
126 int k2 = d2->__givePrescribedEquationNumber();
127 if ( nsd == 2 ) {
128 if ( k1 ) {
129 C.at(k1, 1) = coords.at(1) - xbar;
130 C.at(k1, 4) = coords.at(2) - ybar;
131 }
132
133 if ( k2 ) {
134 C.at(k2, 2) = coords.at(2) - ybar;
135 C.at(k2, 3) = coords.at(1) - xbar;
136 }
137 } else { // nsd == 3
138 Dof *d3 = n->giveDofWithID( this->dofs[2] );
139 int k3 = d3->__givePrescribedEquationNumber();
140
141 if ( k1 ) {
142 C.at(k1, 1) = coords.at(1) - xbar;
143 C.at(k1, 6) = coords.at(2) - ybar;
144 C.at(k1, 5) = coords.at(3) - zbar;
145 }
146 if ( k2 ) {
147 C.at(k2, 2) = coords.at(2) - ybar;
148 C.at(k2, 9) = coords.at(1) - xbar;
149 C.at(k2, 4) = coords.at(3) - zbar;
150 }
151 if ( k3 ) {
152 C.at(k3, 3) = coords.at(3) - zbar;
153 C.at(k3, 8) = coords.at(1) - xbar;
154 C.at(k3, 7) = coords.at(2) - ybar;
155 }
156 }
157 }
158}
159
160
161void PrescribedGradient :: computeField(FloatArray &sigma, TimeStep *tStep)
162{
163 EngngModel *emodel = this->domain->giveEngngModel();
165 FloatArray R_c(npeq), R_ext(npeq);
166
167 R_c.zero();
168 R_ext.zero();
169 emodel->assembleVector( R_c, tStep, InternalForceAssembler(), VM_Total,
171 emodel->assembleVector( R_ext, tStep, ExternalForceAssembler(), VM_Total,
173 R_c.subtract(R_ext);
174
175 // Condense it;
176 FloatMatrix C;
178 sigma.beTProductOf(C, R_c);
179 sigma.times( 1. / this->domainSize(this->giveDomain(), this->giveSetNumber()) );
180}
181
182
183void PrescribedGradient :: computeTangent(FloatMatrix &tangent, TimeStep *tStep)
184// a = [a_c; a_f];
185// K.a = [R_c,0];
186// [K_cc, K_cf; K_fc, K_ff].[a_c;a_f] = [R_c; 0];
187// a_c = d.[x-x_b] = [x-x_b].d = C.d
188// E = C'.(K_cc - K_cf.K_ff^(-1).K_fc).C
189// = C'.(K_cc.C - K_cf.(K_ff^(-1).(K_fc.C)))
190// = C'.(K_cc.C - K_cf.a)
191// = C'.X
192{
193 // Fetch some information from the engineering model
194 EngngModel *rve = this->giveDomain()->giveEngngModel();
196 std :: unique_ptr< SparseLinearSystemNM >solver( classFactory.createSparseLinSolver( ST_Petsc, this->domain, this->domain->giveEngngModel() ) ); // = rve->giveLinearSolver();
197 SparseMtrxType stype = solver->giveRecommendedMatrix(true);
200
201 // Set up and assemble tangent FE-matrix which will make up the sensitivity analysis for the macroscopic material tangent.
202 std :: unique_ptr< SparseMtrx >Kff( classFactory.createSparseMtrx(stype) );
203 std :: unique_ptr< SparseMtrx >Kfp( classFactory.createSparseMtrx(stype) );
204 std :: unique_ptr< SparseMtrx >Kpf( classFactory.createSparseMtrx(stype) );
205 std :: unique_ptr< SparseMtrx >Kpp( classFactory.createSparseMtrx(stype) );
206 if ( !Kff ) {
207 OOFEM_ERROR("Couldn't create sparse matrix of type %d\n", stype);
208 }
209 Kff->buildInternalStructure(rve, 1, fnum);
210 Kfp->buildInternalStructure(rve, 1, fnum, pnum);
211 Kpf->buildInternalStructure(rve, 1, pnum, fnum);
212 Kpp->buildInternalStructure(rve, 1, pnum);
213 rve->assemble(*Kff, tStep, TangentAssembler(TangentStiffness), fnum, this->domain);
214 rve->assemble(*Kfp, tStep, TangentAssembler(TangentStiffness), fnum, pnum, this->domain);
215 rve->assemble(*Kpf, tStep, TangentAssembler(TangentStiffness), pnum, fnum, this->domain);
216 rve->assemble(*Kpp, tStep, TangentAssembler(TangentStiffness), pnum, this->domain);
217
218 FloatMatrix C, X, Kpfa, KfpC, a;
219
221 Kpf->timesT(C, KfpC);
222 solver->solve(*Kff, KfpC, a);
223 Kpp->times(C, X);
224 Kpf->times(a, Kpfa);
225 X.subtract(Kpfa);
226 tangent.beTProductOf(C, X);
227 tangent.times( 1. / this->domainSize(this->giveDomain(), this->giveSetNumber()) );
228}
229
230
231void PrescribedGradient :: initializeFrom(InputRecord &ir)
232{
233 GeneralBoundaryCondition :: initializeFrom(ir);
234 PrescribedGradientHomogenization :: initializeFrom(ir);
235}
236
237
238void PrescribedGradient :: giveInputRecord(DynamicInputRecord &input)
239{
240 GeneralBoundaryCondition :: giveInputRecord(input);
241 PrescribedGradientHomogenization :: giveInputRecord(input);
242}
243} // end namespace oofem
#define REGISTER_BoundaryCondition(class)
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
DofIDItem giveDofID() const
Definition dof.h:276
DofManager * giveDofManager() const
Definition dof.h:123
virtual int __givePrescribedEquationNumber()=0
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
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).
FloatArray & giveCenterCoordinate()
Returns the center coordinate.
virtual void updateCoefficientMatrix(FloatMatrix &C)
#define OOFEM_ERROR(...)
Definition error.h:79
ClassFactory & classFactory

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