OOFEM 3.0
Loading...
Searching...
No Matches
prescribedmean.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 "prescribedmean.h"
36#include "classfactory.h"
37#include "masterdof.h"
38#include "domain.h"
39#include "feinterpol.h"
40#include "gausspoint.h"
41#include "sparsemtrx.h"
42#include "function.h"
43#include "mathfem.h"
44
45#ifdef _OPENMP
46#include <omp.h>
47#endif
48
49namespace oofem
50{
51
52double PrescribedMean :: domainSize;
53
54
56
57void
58PrescribedMean :: initializeFrom(InputRecord &ir)
59{
60 GeneralBoundaryCondition :: initializeFrom(ir);
61
65
66 elementEdges = false;
68
69 int newdofid = this->domain->giveNextFreeDofID();
70 lambdaIDs.clear();
71 lambdaIDs.followedBy(newdofid);
72 lambdaDman->appendDof( new MasterDof( lambdaDman.get(), ( DofIDItem )newdofid ));
73
74 domainSize=-1.;
75
76}
77
78void
79PrescribedMean :: assemble(SparseMtrx &answer, TimeStep *tStep, CharType type,
80 const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s, double scale, void*lock)
81{
82
83 if ( type != TangentStiffnessMatrix && type != StiffnessMatrix ) {
84 return;
85 }
86
88
89 IntArray c_loc, r_loc;
90 lambdaDman->giveLocationArray(lambdaIDs, r_loc, r_s);
91 lambdaDman->giveLocationArray(lambdaIDs, c_loc, c_s);
92
93 for ( int i = 1; i <= elements.giveSize(); i++ ) {
94 int elementID = elements.at(i);
95 Element *thisElement = this->giveDomain()->giveElement(elementID);
96 FEInterpolation *interpolator = thisElement->giveInterpolation(DofIDItem(dofid));
97
98 auto iRule = (elementEdges) ? (interpolator->giveBoundaryIntegrationRule(3, sides.at(i), thisElement->giveGeometryType())) :
99 (interpolator->giveIntegrationRule(3, thisElement->giveGeometryType()));
100
101 for ( GaussPoint * gp: * iRule ) {
102 FloatArray lcoords = gp->giveNaturalCoordinates();
103 FloatArray N; //, a;
104 FloatMatrix temp, tempT;
105 double detJ = 0.0;
106 IntArray dofids={(DofIDItem) this->dofid}, r_Sideloc, c_Sideloc;
107
108 if (elementEdges) {
109 // Compute boundary integral
110 auto boundaryNodes = interpolator->boundaryGiveNodes(sides.at(i), thisElement->giveGeometryType() );
111 interpolator->boundaryEvalN(N, sides.at(i), lcoords, FEIElementGeometryWrapper(thisElement));
112 detJ = fabs ( interpolator->boundaryGiveTransformationJacobian(sides.at(i), lcoords, FEIElementGeometryWrapper(thisElement)) );
113 // Retrieve locations for dofs on boundary
114 thisElement->giveBoundaryLocationArray(r_Sideloc, boundaryNodes, dofids, r_s);
115 thisElement->giveBoundaryLocationArray(c_Sideloc, boundaryNodes, dofids, c_s);
116 } else {
117 interpolator->evalN(N, lcoords, FEIElementGeometryWrapper(thisElement));
118 detJ = fabs ( interpolator->giveTransformationJacobian(lcoords, FEIElementGeometryWrapper(thisElement) ) );
119 IntArray DofIDStemp, rloc, cloc;
120
121 thisElement->giveLocationArray(rloc, r_s, &DofIDStemp);
122 thisElement->giveLocationArray(cloc, c_s, &DofIDStemp);
123
124 r_Sideloc.clear();
125 c_Sideloc.clear();
126 for (int j=1; j<=DofIDStemp.giveSize(); j++) {
127 if ( DofIDStemp.at(j) == dofids.at(1) ) {
128 r_Sideloc.followedBy(rloc.at(j));
129 c_Sideloc.followedBy(cloc.at(j));
130 }
131 }
132 }
133
134 // delta p part:
135 temp = FloatMatrix::fromArray(N * (scale * detJ * gp->giveWeight() / domainSize));
136 tempT.beTranspositionOf(temp);
137#ifdef _OPENMP
138 if (lock) omp_set_lock(static_cast<omp_lock_t*>(lock));
139#endif
140 answer.assemble(r_Sideloc, c_loc, temp);
141 answer.assemble(r_loc, c_Sideloc, tempT);
142#ifdef _OPENMP
143 if (lock) omp_set_lock(static_cast<omp_lock_t*>(lock));
144#endif
145 }
146 }
147}
148
149void
150PrescribedMean :: assembleVector(FloatArray &answer, TimeStep *tStep,
151 CharType type, ValueModeType mode,
152 const UnknownNumberingScheme &s, FloatArray *eNorm,
153 void*lock)
154{
155
156 if ( type == InternalForcesVector ) {
157 giveInternalForcesVector(answer, tStep, type, mode, s, eNorm, lock);
158 } else if ( type == ExternalForcesVector ) {
159 giveExternalForcesVector(answer, tStep, type, mode, s, lock);
160 }
161}
162
163void
164PrescribedMean :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep,
165 CharType type, ValueModeType mode,
166 const UnknownNumberingScheme &s,
167 FloatArray *eNorm,
168 void*lock)
169{
171
172 // Fetch unknowns of this boundary condition
173 IntArray lambdaLoc;
174 FloatArray lambda;
175 lambdaDman->giveUnknownVector(lambda, lambdaIDs, mode, tStep);
176 lambdaDman->giveLocationArray(lambdaIDs, lambdaLoc, s);
177
178 for ( int i = 1; i <= elements.giveSize(); i++ ) {
179 int elementID = elements.at(i);
180 Element *thisElement = this->giveDomain()->giveElement(elementID);
181 FEInterpolation *interpolator = thisElement->giveInterpolation(DofIDItem(dofid));
182
183 auto iRule = elementEdges ?
184 interpolator->giveBoundaryIntegrationRule(3, sides.at(i), thisElement->giveGeometryType()) :
185 interpolator->giveIntegrationRule(3, thisElement->giveGeometryType());
186
187 for ( auto &gp: *iRule ) {
188 FloatArray lcoords = gp->giveNaturalCoordinates();
189 FloatArray a, N, pressureEqns, lambdaEqns;
190 IntArray dofids={(DofIDItem) this->dofid}, locationArray;
191 double detJ = 0.0;
192
193 if (elementEdges) {
194 // Compute integral
195 auto boundaryNodes = interpolator->boundaryGiveNodes(sides.at(i), thisElement->giveGeometryType() );
196 thisElement->computeBoundaryVectorOf(boundaryNodes, dofids, VM_Total, tStep, a);
197 interpolator->boundaryEvalN(N, sides.at(i), lcoords, FEIElementGeometryWrapper(thisElement));
198 detJ = fabs ( interpolator->boundaryGiveTransformationJacobian(sides.at(i), lcoords, FEIElementGeometryWrapper(thisElement)) );
199
200 // Retrieve locations for dofs with dofids
201 thisElement->giveBoundaryLocationArray(locationArray, boundaryNodes, dofids, s);
202 } else {
203 thisElement->computeVectorOf(dofids, VM_Total, tStep, a);
204 interpolator->evalN(N, lcoords, FEIElementGeometryWrapper(thisElement));
205 detJ = fabs ( interpolator->giveTransformationJacobian(lcoords, FEIElementGeometryWrapper(thisElement)));
206
207 IntArray DofIDStemp, loc;
208
209 thisElement->giveLocationArray(loc, s, &DofIDStemp);
210
211 locationArray.clear();
212 for (int j = 1; j <= DofIDStemp.giveSize(); j++) {
213 if ( DofIDStemp.at(j) == dofids.at(1) ) {
214 locationArray.followedBy(loc.at(j));
215 }
216 }
217 }
218
219 // delta p part:
220 pressureEqns = N*detJ*gp->giveWeight()*lambda.at(1)*(1.0/domainSize);
221
222 // delta lambda part
223 lambdaEqns.resize(1);
224 lambdaEqns.at(1) = N.dotProduct(a);
225 lambdaEqns.times(detJ*gp->giveWeight()*1.0/domainSize);
226 lambdaEqns.at(1) = lambdaEqns.at(1);
227
228#ifdef _OPENMP
229 if (lock) omp_set_lock(static_cast<omp_lock_t*>(lock));
230#endif
231 // delta p part
232 answer.assemble(pressureEqns, locationArray);
233
234 // delta lambda part
235 answer.assemble(lambdaEqns, lambdaLoc);
236#ifdef _OPENMP
237 if (lock) omp_unset_lock(static_cast<omp_lock_t*>(lock));
238#endif
239 }
240 }
241
242}
243
244void
245PrescribedMean :: giveExternalForcesVector(FloatArray &answer, TimeStep *tStep,
246 CharType type, ValueModeType mode,
247 const UnknownNumberingScheme &s,
248 void* lock)
249{
251
252 FloatArray temp;
253 IntArray lambdaLoc;
254
255 temp.resize(1);
256 temp.at(1) = c;
257
258 lambdaDman->giveLocationArray(lambdaIDs, lambdaLoc, s);
259#ifdef _OPENMP
260 if (lock) omp_set_lock(static_cast<omp_lock_t*>(lock));
261#endif
262 answer.assemble(temp, lambdaLoc);
263#ifdef _OPENMP
264 if (lock) omp_set_lock(static_cast<omp_lock_t*>(lock));
265#endif
266 // Finally, compute value of loadtimefunction
267 double factor;
268 factor = this->giveTimeFunction()->evaluate(tStep, mode);
269 answer.times(factor);
270}
271
272void
273PrescribedMean :: computeDomainSize()
274{
275 if ( domainSize > 0.0 ) return;
276
277
278 if ( elementEdges ) {
279 IntArray setList = ((GeneralBoundaryCondition *)this)->giveDomain()->giveSet(set)->giveBoundaryList();
280
281 elements.resize(setList.giveSize() / 2);
282 sides.resize(setList.giveSize() / 2);
283
284 for (int i = 1; i <= setList.giveSize(); i += 2) {
285 elements.at(i/2+1) = setList.at(i);
286 sides.at(i/2+1) = setList.at(i+1);
287 }
288 } else {
289 IntArray setList = ((GeneralBoundaryCondition *)this)->giveDomain()->giveSet(set)->giveElementList();
290 elements = setList;
291 }
292
293 domainSize = 0.0;
294
295 for ( int i = 1; i <= elements.giveSize(); i++ ) {
296 int elementID = elements.at(i);
297 Element *thisElement = this->giveDomain()->giveElement(elementID);
298 FEInterpolation *interpolator = thisElement->giveInterpolation(DofIDItem(dofid));
299
300 auto iRule = elementEdges ?
301 interpolator->giveBoundaryIntegrationRule(3, sides.at(i), thisElement->giveGeometryType()) :
302 interpolator->giveIntegrationRule(3, thisElement->giveGeometryType());
303
304 for ( auto &gp: *iRule ) {
305 FloatArray lcoords = gp->giveNaturalCoordinates();
306
307 double detJ;
308 if ( elementEdges ) {
309 detJ = fabs ( interpolator->boundaryGiveTransformationJacobian(sides.at(i), lcoords, FEIElementGeometryWrapper(thisElement)) );
310 } else {
311 detJ = fabs ( interpolator->giveTransformationJacobian(lcoords, FEIElementGeometryWrapper(thisElement)) );
312 }
313 domainSize = domainSize + detJ*gp->giveWeight();
314 }
315 }
316 printf("%f\n", domainSize);
317}
318
319}
#define N(a, b)
#define REGISTER_BoundaryCondition(class)
virtual void giveBoundaryLocationArray(IntArray &locationArray, const IntArray &bNodes, const UnknownNumberingScheme &s, IntArray *dofIds=NULL)
Definition element.C:485
virtual FEInterpolation * giveInterpolation() const
Definition element.h:648
void giveLocationArray(IntArray &locationArray, const UnknownNumberingScheme &s, IntArray *dofIds=NULL) const
Definition element.C:429
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Definition element.C:103
void computeBoundaryVectorOf(const IntArray &bNodes, const IntArray &dofIDMask, ValueModeType u, TimeStep *tStep, FloatArray &answer, bool padding=false)
Definition element.C:163
virtual Element_Geometry_Type giveGeometryType() const =0
virtual std::unique_ptr< IntegrationRule > giveBoundaryIntegrationRule(int order, int boundary, const Element_Geometry_Type) const
Definition feinterpol.C:101
virtual IntArray boundaryGiveNodes(int boundary, const Element_Geometry_Type) const =0
virtual double boundaryGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
Definition feinterpol.C:81
virtual std::unique_ptr< IntegrationRule > giveIntegrationRule(int order, const Element_Geometry_Type) const
Definition feinterpol.C:90
virtual void boundaryEvalN(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
Domain * giveDomain() const
Definition femcmpnn.h:97
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
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
void times(double s)
Definition floatarray.C:834
static FloatMatrix fromArray(const FloatArray &vector, bool transpose=false)
void beTranspositionOf(const FloatMatrix &src)
int set
Set number for boundary condition to be applied to.
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
void giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, CharType type, ValueModeType mode, const UnknownNumberingScheme &s, FloatArray *eNorm=nullptr, void *lock=nullptr)
static double domainSize
void giveExternalForcesVector(FloatArray &answer, TimeStep *tStep, CharType type, ValueModeType mode, const UnknownNumberingScheme &s, void *lock=nullptr)
std::unique_ptr< Node > lambdaDman
virtual int assemble(const IntArray &loc, const FloatMatrix &mat)=0
#define _IFT_GeneralBoundaryCondition_set
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define _IFT_PrescribedMean_DofID
#define _IFT_PrescribedMean_Edge
#define _IFT_PrescribedMean_Mean

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