OOFEM 3.0
Loading...
Searching...
No Matches
freeminterface.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 "freeminterface.h"
36#include "errorestimator.h"
37#include "domain.h"
38#include "node.h"
39#include "element.h"
40#include "connectivitytable.h"
41#include "mathfem.h"
42#include "remeshingcrit.h"
43#include "classfactory.h"
44
45#include <list>
46
47namespace oofem {
49
50MesherInterface :: returnCode
51FreemInterface :: createMesh(TimeStep *tStep, int domainNumber, int domainSerNum, Domain **dNew)
52{
53 * dNew = NULL;
54 if ( this->createInput(this->domain, tStep) ) {
56 } else {
57 return MI_FAILED;
58 }
59}
60
61int
62FreemInterface :: createInput(Domain *d, TimeStep *tStep)
63{
64 int nnodes = d->giveNumberOfDofManagers(), nelem = d->giveNumberOfElements();
65 double density;
66 FILE *outputStrem;
67 Node *inode;
68 Element *ielem;
69
70 outputStrem = fopen("freem.bmf", "w");
71 // print header for 2D
72 fprintf(outputStrem, "nbnodes %d nbelem %d \n", nnodes, nelem);
73
74 /* mesh densities smoothing */
75 // query nodal absolute densities
76 FloatArray nodalDensities(nnodes);
77 for ( int i = 1; i <= nnodes; i++ ) {
78 nodalDensities.at(i) = d->giveErrorEstimator()->giveRemeshingCrit()->giveRequiredDofManDensity(i, tStep);
79 }
80
81 this->smoothNodalDensities(d, nodalDensities, tStep);
82 /* end of smoothing */
83
84 // loop over nodes
85 for ( int i = 1; i <= nnodes; i++ ) {
86 //density = d->giveErrorEstimator ()->giveRemeshingCrit()->giveRequiredDofManDensity (i, tStep, 1);
87 //density = d->giveErrorEstimator ()->giveRemeshingCrit()->giveDofManDensity (i) / nodalDensities.at(i);
88 density = nodalDensities.at(i);
89 inode = d->giveNode(i);
90 fprintf(outputStrem, "backgroungMeshNode %d x %e y %e density %e\n", i, inode->giveCoordinate(1), inode->giveCoordinate(2), density);
91 }
92
93 for ( int i = 1; i <= nelem; i++ ) {
94 ielem = d->giveElement(i);
95 if ( ielem->giveGeometryType() != EGT_quad_1 ) {
96 OOFEM_ERROR("unsupported element type (not a bilinear quad)");
97 }
98
99 fprintf( outputStrem, "backgroundMeshElem %d nodes 4 %d %d %d %d\n", i,
100 ielem->giveNode(1)->giveNumber(), ielem->giveNode(2)->giveNumber(),
101 ielem->giveNode(3)->giveNumber(), ielem->giveNode(4)->giveNumber() );
102 }
103
104 fclose(outputStrem);
105
106 OOFEM_LOG_INFO("freem.bmf file created\n");
107 return 1;
108}
109
110void
111FreemInterface :: smoothNodalDensities(Domain *d, FloatArray &nodalDensities, TimeStep *tStep)
112{
113 std :: list< int > queue;
114
115 // loop over nodes
116 int nnodes = d->giveNumberOfDofManagers();
117 for ( int i = 1; i <= nnodes; i++ ) {
118 if ( !dynamic_cast< Node * >( d->giveDofManager(i) ) ) {
119 continue;
120 }
121
122 queue.clear();
123 queue.push_front(i);
124
125 while ( !queue.empty() ) {
126 // extract candidate
127 int candidate = * ( queue.begin() );
128 queue.erase( queue.begin() );
129
130 Node *candNode = static_cast< Node * >( d->giveDofManager(candidate) );
131 // find candidate neighbours
132 const IntArray *candidateConnectivity = d->giveConnectivityTable()->giveDofManConnectivityArray(candidate);
133 for ( int j = 1; j <= candidateConnectivity->giveSize(); j++ ) {
134 Element *jelem = d->giveElement( candidateConnectivity->at(j) );
135 int jelemNodes = jelem->giveNumberOfNodes();
136 for ( int k = 1; k <= jelemNodes; k++ ) {
137 int neighbour = jelem->giveNode(k)->giveNumber();
138 if ( neighbour == candidate ) {
139 continue;
140 }
141
142 // neighbour found, check if smoothing necessary
143 const auto &neighbourCoords = jelem->giveNode(k)->giveCoordinates();
144 double dist = distance(candNode->giveCoordinates(), neighbourCoords);
145 // overshoot criteria
146 if ( ( ( nodalDensities.at(neighbour) / nodalDensities.at(candidate) ) > 1.3 ) &&
147 ( nodalDensities.at(neighbour) > 1.0 * dist ) ) {
148 // increase candidate nodal density
149 nodalDensities.at(neighbour) = max( 1.0 * dist, nodalDensities.at(candidate) );
150 // printf ("o");
151 // put candidate into queue if not yet added present
152 bool found = false;
153 for ( int q: queue ) {
154 if ( q == neighbour ) {
155 found = true;
156 break;
157 }
158 }
159
160 if ( !found ) {
161 queue.push_front(neighbour);
162 }
163
164 // end overshoot criteria
165 } else if ( ( nodalDensities.at(neighbour) - nodalDensities.at(candidate) ) / dist > 2.5 ) {
166 // max gradient criteria
167 nodalDensities.at(neighbour) = nodalDensities.at(candidate) + 2.2 * dist;
168 //printf ("g");
169 // put candidate into queue if not yet added present
170 bool found = false;
171 for ( int q: queue ) {
172 if ( q == neighbour ) {
173 found = true;
174 break;
175 }
176 }
177
178 if ( !found ) {
179 queue.push_front(neighbour);
180 }
181 }
182 }
183 }
184 } // end loop over queue
185 }
186}
187} // end namespace oofem
#define REGISTER_Mesher(class, type)
const IntArray * giveDofManConnectivityArray(int dofman)
double giveCoordinate(int i) const
Definition dofmanager.h:383
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
ErrorEstimator * giveErrorEstimator()
Definition domain.C:1537
ConnectivityTable * giveConnectivityTable()
Definition domain.C:1240
int giveNumberOfElements() const
Returns number of elements in domain.
Definition domain.h:463
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
Definition domain.h:461
DofManager * giveDofManager(int n)
Definition domain.C:317
Element * giveElement(int n)
Definition domain.C:165
Node * giveNode(int n)
Definition domain.h:398
Node * giveNode(int i) const
Definition element.h:629
virtual int giveNumberOfNodes() const
Definition element.h:703
virtual Element_Geometry_Type giveGeometryType() const =0
virtual RemeshingCriteria * giveRemeshingCrit()=0
int giveNumber() const
Definition femcmpnn.h:104
double & at(Index i)
Definition floatarray.h:202
int createInput(Domain *d, TimeStep *tStep)
Creates the mesher input, containing the required mesh density information.
void smoothNodalDensities(Domain *d, FloatArray &nodalDensities, TimeStep *tStep)
Service for smoothing the densities for freem.
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
virtual double giveRequiredDofManDensity(int num, TimeStep *tStep, int relative=0)=0
#define OOFEM_ERROR(...)
Definition error.h:79
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
double distance(const FloatArray &x, const FloatArray &y)

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