OOFEM 3.0
Loading...
Searching...
No Matches
primvarmapper.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 "primvarmapper.h"
36#include "domain.h"
37#include "dofmanager.h"
38#include "linsystsolvertype.h"
40#include "engngm.h"
41#include "gausspoint.h"
42#include "feinterpol.h"
43#include "spatiallocalizer.h"
44#include "sparsemtrx.h"
45#include "sparselinsystemnm.h"
46#include "classfactory.h"
47#include "timestep.h"
48#include "activebc.h"
52#include "mathfem.h"
53
54#include <fstream>
55
56namespace oofem {
57PrimaryVariableMapper :: PrimaryVariableMapper() { }
58
59PrimaryVariableMapper :: ~PrimaryVariableMapper() { }
60
61LSPrimaryVariableMapper :: LSPrimaryVariableMapper()
62{ }
63
64LSPrimaryVariableMapper :: ~LSPrimaryVariableMapper()
65{ }
66
67void LSPrimaryVariableMapper :: mapPrimaryVariables(FloatArray &oU, Domain &iOldDom, Domain &iNewDom, ValueModeType iMode, TimeStep &iTStep)
68{
69 EngngModel *engngMod = iNewDom.giveEngngModel();
71
72
73 const int dim = iNewDom.giveNumberOfSpatialDimensions();
74
75 int numElNew = iNewDom.giveNumberOfElements();
76
77 // Count dofs
78 int numDofsNew = engngMod->giveNumberOfDomainEquations( 1, num );
79
80
81 oU.resize(numDofsNew);
82 oU.zero();
83
84 FloatArray du(numDofsNew);
85 du.zero();
86
87 FloatArray res(numDofsNew);
88
89 std :: unique_ptr< SparseMtrx > K;
90 std :: unique_ptr< SparseLinearSystemNM > solver;
91
92 solver = classFactory.createSparseLinSolver(ST_Petsc, & iOldDom, engngMod);
93 if (!solver) {
94 solver = classFactory.createSparseLinSolver(ST_Direct, & iOldDom, engngMod);
95 }
96 K = classFactory.createSparseMtrx(solver->giveRecommendedMatrix(true));
97
98 K->buildInternalStructure( engngMod, iNewDom.giveNumber(), num );
99
100 int maxIter = 1;
101
102 for ( int iter = 0; iter < maxIter; iter++ ) {
103 K->zero();
104 res.zero();
105
106
107 // Contribution from elements
108 for ( int elIndex = 1; elIndex <= numElNew; elIndex++ ) {
109 StructuralElement *elNew = dynamic_cast< StructuralElement * >( iNewDom.giveElement(elIndex) );
110 if ( elNew == NULL ) {
111 OOFEM_ERROR("Failed to cast Element new to StructuralElement.");
112 }
113
115 // Compute residual
116
117 // Count element dofs
118 int numElNodes = elNew->giveNumberOfDofManagers();
119 int numElDofs = 0;
120 for ( int i = 1; i <= numElNodes; i++ ) {
121 numElDofs += elNew->giveDofManager(i)->giveNumberOfDofs();
122 }
123
124 FloatArray elRes(numElDofs);
125 elRes.zero();
126
127 IntArray elDofsGlob;
128 elNew->giveLocationArray( elDofsGlob, num );
129
130
131 // Loop over Gauss points
132 for ( int intRuleInd = 0; intRuleInd < elNew->giveNumberOfIntegrationRules(); intRuleInd++ ) {
133
134 for ( GaussPoint *gp: *elNew->giveIntegrationRule(intRuleInd) ) {
135
136 // New N-matrix
137 FloatMatrix NNew;
138 elNew->computeNmatrixAt(gp->giveNaturalCoordinates(), NNew);
139
140
142 // Global coordinates of GP
143 const FloatArray &localCoord = gp->giveNaturalCoordinates();
144 FloatArray globalCoord;
145 elNew->computeGlobalCoordinates(globalCoord, localCoord);
147
148
149 // Localize element and point in the old domain
150 FloatArray localCoordOld(dim), pointCoordOld(dim);
151 StructuralElement *elOld = dynamic_cast< StructuralElement * >( iOldDom.giveSpatialLocalizer()->giveElementClosestToPoint(localCoordOld, pointCoordOld, globalCoord, 0) );
152 if ( elOld == NULL ) {
153 OOFEM_ERROR("Failed to cast Element old to StructuralElement.");
154 }
155
156
157 // Compute N-Matrix for the old element
158 FloatMatrix NOld;
159 elOld->computeNmatrixAt(localCoordOld, NOld);
160
161 // Fetch nodal displacements for the new element
162 FloatArray nodeDispNew( elDofsGlob.giveSize() );
163
164
165 int dofsPassed = 1;
166 for ( int elNode: elNew->giveDofManArray() ) {
167// DofManager *dMan = iNewDom.giveNode(elNode);
168 DofManager *dMan = iNewDom.giveDofManager(elNode);
169
170 for ( Dof *dof: *dMan ) {
171 if ( elDofsGlob.at(dofsPassed) != 0 ) {
172 nodeDispNew.at(dofsPassed) = oU.at( elDofsGlob.at(dofsPassed) );
173 } else {
174 if ( dof->hasBc(& iTStep) ) {
175 nodeDispNew.at(dofsPassed) = dof->giveBcValue(iMode, & iTStep);
176 }
177 }
178
179 dofsPassed++;
180 }
181 }
182
183
184 FloatArray newDisp;
185 newDisp.beProductOf(NNew, nodeDispNew);
186
187
188 // Fetch nodal displacements for the old element
189 std::vector<double> nodeDispOld_;
190 dofsPassed = 1;
191 IntArray elDofsGlobOld;
192 elOld->giveLocationArray( elDofsGlobOld, num );
193
194// elOld->computeVectorOf(iMode, &(iTStep), nodeDisp);
195 int numElNodesOld = elOld->giveNumberOfDofManagers();
196 for(int nodeIndOld = 1; nodeIndOld <= numElNodesOld; nodeIndOld++) {
197 DofManager *dManOld = elOld->giveDofManager(nodeIndOld);
198
199 for ( Dof *dof: *dManOld ) {
200 if ( elDofsGlobOld.at(dofsPassed) != 0 ) {
201 FloatArray dofUnknowns;
202
203 if(dof->giveEqn() > 0) {
204 dof->giveUnknowns(dofUnknowns, iMode, &iTStep);
205
206#ifdef DEBUG
207 if(!dofUnknowns.isAllFinite()) {
208 OOFEM_ERROR("!dofUnknowns.isAllFinite()")
209 }
210
211 if(dofUnknowns.giveSize() < 1) {
212 OOFEM_ERROR("dofUnknowns.giveSize() < 1")
213 }
214#endif
215 nodeDispOld_.push_back(dofUnknowns.at(1));
216 }
217 else {
218 // TODO: Why does this case occur?
219 nodeDispOld_.push_back(0.0);
220 }
221 } else {
222 if ( dof->hasBc(& iTStep) ) {
223// printf("hasBC.\n");
224#ifdef DEBUG
225 if(!std::isfinite(dof->giveBcValue(iMode, & iTStep))) {
226 OOFEM_ERROR("!std::isfinite(dof->giveBcValue(iMode, & iTStep))")
227 }
228#endif
229 nodeDispOld_.push_back( dof->giveBcValue(iMode, & iTStep) );
230 }
231 else {
232// printf("Unhandled case in LSPrimaryVariableMapper :: mapPrimaryVariables().\n");
233 nodeDispOld_.push_back( 0.0 );
234 }
235 }
236
237 dofsPassed++;
238 }
239
240 }
241
242
243 FloatArray oldDisp;
244 FloatArray nodeDispOld=FloatArray::fromVector(nodeDispOld_);
245 oldDisp.beProductOf(NOld, nodeDispOld);
246
247 FloatArray temp, duu;
248
249#ifdef DEBUG
250 if(!oldDisp.isAllFinite()) {
251 OOFEM_ERROR("!oldDisp.isAllFinite()")
252 }
253
254 if(!newDisp.isAllFinite()) {
255 OOFEM_ERROR("!newDisp.isAllFinite()")
256 }
257#endif
258
259 duu.beDifferenceOf(oldDisp, newDisp);
260 temp.beTProductOf(NNew, duu);
261 double dV = elNew->computeVolumeAround(gp);
262 elRes.add(dV, temp);
263 }
264 }
265
266
268 // Compute matrix
269 FloatMatrix me;
270
271 double mass = 0.0;
272 double density = 1.0;
273 elNew->computeConsistentMassMatrix(me, & iTStep, mass, & density);
274
275#ifdef DEBUG
276 if(!me.isAllFinite()) {
277 OOFEM_ERROR("!me.isAllFinite()")
278 }
279#endif
280
281 K->assemble(elDofsGlob, me);
282 res.assemble(elRes, elDofsGlob);
283 }
284
285
286 // Contribution from active boundary conditions
287 int numBC = iNewDom.giveNumberOfBoundaryConditions();
288 for(int bcInd = 1; bcInd <= numBC; bcInd++) {
289
290 PrescribedGradientBCWeak *activeBC = dynamic_cast<PrescribedGradientBCWeak*> ( iNewDom.giveBc(bcInd) );
291
292 if(activeBC != NULL) {
293 IntArray tractionRows;
294 activeBC->giveTractionLocationArray(tractionRows, num);
295
296 // TODO: Compute correct mass matrix and add residual contribution.
297
298 FloatMatrix mNode(1,1);
299 mNode.beUnitMatrix();
300
301 for(int tracDofInd : tractionRows) {
302 const IntArray tracDofArray = {tracDofInd};
303 K->assemble(tracDofArray, tracDofArray, mNode);
304 }
305
306 }
307
308
309 PrescribedGradientBCNeumann *neumannBC = dynamic_cast<PrescribedGradientBCNeumann*> ( iNewDom.giveBc(bcInd) );
310
311 if(neumannBC != NULL) {
312 IntArray stressRows;
313 neumannBC->giveStressLocationArray(stressRows, num);
314
315 FloatMatrix massMtrxBc( stressRows.giveSize(), stressRows.giveSize() );
316 massMtrxBc.beUnitMatrix(); // TODO: Compute correct mass matrix and add residual contribution.
317 K->assemble(stressRows, massMtrxBc);
318 }
319
320 }
321
322#ifdef DEBUG
323 if(!res.isAllFinite()) {
324 OOFEM_ERROR("!res.isAllFinite()")
325 }
326#endif
327
328// printf("iter: %d res norm: %e\n", iter, res.computeNorm() );
329 K->assembleBegin();
330 K->assembleEnd();
331// K->writeToFile("Kmapping.txt");
332
333 // Solve
334 solver->solve(*K, res, du);
335
336#ifdef DEBUG
337 if(!du.isAllFinite()) {
338 OOFEM_ERROR("!du.isAllFinite()")
339 }
340#endif
341
342 oU.add(du);
343 }
344}
345} /* namespace oofem */
int giveNumberOfDofs() const
Definition dofmanager.C:287
SpatialLocalizer * giveSpatialLocalizer()
Definition domain.C:1255
int giveNumberOfBoundaryConditions() const
Returns number of boundary conditions in domain.
Definition domain.h:469
int giveNumber()
Returns domain number.
Definition domain.h:281
int giveNumberOfElements() const
Returns number of elements in domain.
Definition domain.h:463
DofManager * giveDofManager(int n)
Definition domain.C:317
Element * giveElement(int n)
Definition domain.C:165
int giveNumberOfSpatialDimensions()
Returns number of spatial dimensions.
Definition domain.C:1137
GeneralBoundaryCondition * giveBc(int n)
Definition domain.C:246
EngngModel * giveEngngModel()
Definition domain.C:419
virtual int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
Definition element.C:1225
const IntArray & giveDofManArray() const
Definition element.h:611
int giveNumberOfIntegrationRules()
Definition element.h:894
void giveLocationArray(IntArray &locationArray, const UnknownNumberingScheme &s, IntArray *dofIds=NULL) const
Definition element.C:429
virtual IntegrationRule * giveIntegrationRule(int i)
Definition element.h:899
virtual int giveNumberOfDofManagers() const
Definition element.h:695
DofManager * giveDofManager(int i) const
Definition element.C:553
virtual double computeVolumeAround(GaussPoint *gp)
Definition element.h:530
virtual int giveNumberOfDomainEquations(int di, const UnknownNumberingScheme &num)
Definition engngm.C:452
void assemble(const FloatArray &fe, const IntArray &loc)
Definition floatarray.C:616
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
bool isAllFinite() const
Returns true if no element is NAN or infinite.
Definition floatarray.C:195
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
static FloatArray fromVector(const std::vector< double > &v)
Definition floatarray.C:131
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 add(const FloatArray &src)
Definition floatarray.C:218
bool isAllFinite() const
Returns true if no element is NAN or infinite.
void beUnitMatrix()
Sets receiver to unity matrix.
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
void giveStressLocationArray(IntArray &oCols, const UnknownNumberingScheme &r_s)
virtual void giveTractionLocationArray(IntArray &rows, const UnknownNumberingScheme &s)
virtual void computeConsistentMassMatrix(FloatMatrix &answer, TimeStep *tStep, double &mass, const double *ipDensity=NULL)
virtual void computeNmatrixAt(const FloatArray &iLocCoord, FloatMatrix &answer)
#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