1 /*
2 Copyright (C) 1998 Dennis Roddeman
3 email: dennis.roddeman@feat.nl
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation
18 59 Temple Place, Suite 330, Boston, MA, 02111-1307, USA
19 */
20
21 #include "tochnog.h"
22
23 #define EPS_COORD 1.e-10
24
generate_spring(long int icontrol)25 void generate_spring( long int icontrol )
26
27 {
28 long int j=0, n=0, inod=0, jnod=0, max_node=0, max_element=0,
29 element_group=0, in_geometry=0, length=0, swit=0, ldum=0,
30 correct_elements=0, length_node_element_inod=0, length_node_element_jnod=0,
31 control_mesh_generate_contactspring_element_specified=0,
32 iel=0, element=0, name=0, element_name0=0, element_name1=0,
33 element0_in_node_element_inod=0, element0_in_node_element_jnod=0,
34 element1_in_node_element_inod=0, element1_in_node_element_jnod=0,
35 control_mesh_generate_spring[3], el[1+MNOL],
36 control_mesh_generate_contactspring_element[2],
37 geometry_entity[2], *in_geometry_list=NULL,
38 *node_element_inod=NULL, *node_element_jnod=NULL;
39 double distance=0., rdum=0., ddum[MDIM], *coordi=NULL, *coordj=NULL;
40 long int zero=0, mnolnuknwn=npointmax*nuknwn, idum[1]={0},
41 length_nei=1+npointmax*ndim+npointmax+2;
42 double *tmp_element_dof=NULL, *dworknei=NULL;
43 tmp_element_dof = get_new_dbl(mnolnuknwn);
44 dworknei = get_new_dbl(length_nei);
45
46 array_set( control_mesh_generate_contactspring_element, -ALL, 2 );
47 array_set( dworknei, 0, length_nei );
48 db_highest_index( ELEMENT, max_element, VERSION_NORMAL );
49 db_max_index( NODE_START_REFINED, max_node, VERSION_NORMAL, GET );
50
51 if ( db_active_index(CONTROL_MESH_GENERATE_SPRING1,icontrol,VERSION_NORMAL) ) {
52 swit = set_swit(-1,-1,"generate_spring");
53 if ( swit ) pri( "In routine GENERATE_SPRING." );
54 db( CONTROL_MESH_GENERATE_SPRING1, icontrol, control_mesh_generate_spring,
55 ddum, ldum, VERSION_NORMAL, GET );
56 element_group = control_mesh_generate_spring[0];
57 array_move( &control_mesh_generate_spring[1], geometry_entity, 2 );
58 for ( inod=0; inod<=max_node; inod++ ) {
59 if ( db_active_index( NODE_START_REFINED, inod, VERSION_NORMAL ) ) {
60 geometry( inod, ddum, geometry_entity, in_geometry, rdum, ddum, rdum,
61 ddum, NODE_START_REFINED, PROJECT_EXACT, VERSION_NORMAL );
62 if ( in_geometry ) {
63 max_element++;
64 el[0] = -SPRING1;
65 el[1] = inod;
66 length = 2;
67 db( ELEMENT, max_element, el, ddum, length,
68 VERSION_NORMAL, PUT );
69 length = 1;
70 db( ELEMENT_GROUP, max_element, &element_group, ddum, length,
71 VERSION_NORMAL, PUT );
72 length = 1;
73 db( ELEMENT_MACRO_GENERATE, max_element, &icontrol,
74 ddum, length, VERSION_NORMAL, PUT );
75 db( ELEMENT_DOF, max_element, idum, tmp_element_dof, mnolnuknwn, VERSION_NORMAL, PUT );
76 db( ELEMENT_DOF_INITIALISED, max_element, &zero, ddum, length, VERSION_NORMAL, PUT );
77 db( NONLOCAL_ELEMENT_INFO, max_element, idum, dworknei, length_nei, VERSION_NORMAL, PUT );
78 }
79 }
80 }
81
82 mesh_has_changed( VERSION_NORMAL );
83 if ( swit ) pri( "Out routine GENERATE_SPRING." );
84 }
85
86
87 if ( db_active_index(CONTROL_MESH_GENERATE_SPRING2,icontrol,VERSION_NORMAL) ) {
88 swit = set_swit(-1,-1,"generate_spring");
89 if ( swit ) pri( "In routine GENERATE_SPRING." );
90 db( CONTROL_MESH_GENERATE_SPRING2, icontrol, control_mesh_generate_spring, ddum, ldum,
91 VERSION_NORMAL, GET );
92 in_geometry_list = get_new_int(1+max_node);
93 element_group = control_mesh_generate_spring[0];
94 array_move( &control_mesh_generate_spring[1], geometry_entity, 2 );
95 for ( inod=0; inod<=max_node; inod++ ) {
96 if ( db_active_index( NODE_START_REFINED, inod, VERSION_NORMAL ) ) {
97 geometry( inod, ddum, geometry_entity, in_geometry, rdum, ddum, rdum,
98 ddum, NODE_START_REFINED, PROJECT_EXACT, VERSION_NORMAL );
99 if ( in_geometry ) {
100 in_geometry_list[n] = inod;
101 coordi = db_dbl( NODE_START_REFINED, inod, VERSION_NORMAL );
102 for ( j=0; j<n; j++ ) {
103 jnod = in_geometry_list[j];
104 coordj = db_dbl( NODE_START_REFINED, jnod, VERSION_NORMAL );
105 distance = array_distance( coordi, coordj, ddum, ndim );
106 if ( distance < EPS_COORD ) {
107 max_element++;
108 el[0] = -SPRING2;
109 el[1] = inod;
110 el[2] = jnod;
111 length = 3;
112 db( ELEMENT, max_element, el, ddum, length,
113 VERSION_NORMAL, PUT );
114 length = 1;
115 db( ELEMENT_GROUP, max_element, &element_group, ddum, length,
116 VERSION_NORMAL, PUT );
117 length = 1;
118 db( ELEMENT_MACRO_GENERATE, max_element, &icontrol,
119 ddum, length, VERSION_NORMAL, PUT );
120 db( ELEMENT_DOF, max_element, idum, tmp_element_dof, mnolnuknwn, VERSION_NORMAL, PUT );
121 db( ELEMENT_DOF_INITIALISED, max_element, &zero, ddum, length, VERSION_NORMAL, PUT );
122 db( NONLOCAL_ELEMENT_INFO, max_element, idum, dworknei, length_nei, VERSION_NORMAL, PUT );
123 }
124 }
125 n++;
126 }
127 }
128 }
129 delete[] in_geometry_list;
130
131 mesh_has_changed( VERSION_NORMAL );
132 if ( swit ) pri( "Out routine GENERATE_SPRING." );
133 }
134
135 if ( db_active_index(CONTROL_MESH_GENERATE_CONTACTSPRING,icontrol,VERSION_NORMAL) ) {
136 swit = set_swit(-1,-1,"generate_spring");
137 if ( swit ) pri( "In routine GENERATE_SPRING." );
138 db( CONTROL_MESH_GENERATE_CONTACTSPRING, icontrol,
139 control_mesh_generate_spring, ddum, ldum, VERSION_NORMAL, GET );
140 if ( db( CONTROL_MESH_GENERATE_CONTACTSPRING_ELEMENT, icontrol,
141 control_mesh_generate_contactspring_element, ddum, ldum,
142 VERSION_NORMAL, GET_IF_EXISTS ) ) {
143 control_mesh_generate_contactspring_element_specified = 1;
144 element_name0 = control_mesh_generate_contactspring_element[0];
145 element_name1 = control_mesh_generate_contactspring_element[1];
146 length = 1+max_element;
147 node_element_inod = get_new_int(1+max_element);
148 node_element_jnod = get_new_int(1+max_element);
149 }
150 in_geometry_list = get_new_int(1+max_node);
151 element_group = control_mesh_generate_spring[0];
152 array_move( &control_mesh_generate_spring[1], geometry_entity, 2 );
153 for ( inod=0; inod<=max_node; inod++ ) {
154 if ( db_active_index( NODE_START_REFINED, inod, VERSION_NORMAL ) ) {
155 geometry( inod, ddum, geometry_entity, in_geometry, rdum, ddum, rdum,
156 ddum, NODE_START_REFINED, PROJECT_EXACT, VERSION_NORMAL );
157 if ( in_geometry ) {
158 in_geometry_list[n] = inod;
159 coordi = db_dbl( NODE_START_REFINED, inod, VERSION_NORMAL );
160 for ( j=0; j<n; j++ ) {
161 jnod = in_geometry_list[j];
162 coordj = db_dbl( NODE_START_REFINED, jnod, VERSION_NORMAL );
163 distance = array_distance( coordi, coordj, ddum, ndim );
164 correct_elements = 1;
165 if ( control_mesh_generate_contactspring_element_specified ) {
166 db( NODE_ELEMENT, inod, node_element_inod, ddum,
167 length_node_element_inod, VERSION_NORMAL, GET );
168 db( NODE_ELEMENT, jnod, node_element_jnod, ddum,
169 length_node_element_jnod, VERSION_NORMAL, GET );
170 element0_in_node_element_inod = 0;
171 element1_in_node_element_inod = 0;
172 for ( iel=0; iel<length_node_element_inod; iel++ ) {
173 element = node_element_inod[iel];
174 db( ELEMENT, element, el, ddum, ldum, VERSION_NORMAL, GET );
175 name = el[0];
176 if ( name==element_name0 ) element0_in_node_element_inod = 1;
177 if ( name==element_name1 ) element1_in_node_element_inod = 1;
178 }
179 element0_in_node_element_jnod = 0;
180 element1_in_node_element_jnod = 0;
181 for ( iel=0; iel<length_node_element_jnod; iel++ ) {
182 element = node_element_jnod[iel];
183 db( ELEMENT, element, el, ddum, ldum, VERSION_NORMAL, GET );
184 name = el[0];
185 if ( name==element_name0 ) element0_in_node_element_jnod = 1;
186 if ( name==element_name1 ) element1_in_node_element_jnod = 1;
187 }
188 if ( element0_in_node_element_inod && element1_in_node_element_jnod )
189 correct_elements = 1;
190 else if ( element0_in_node_element_jnod && element1_in_node_element_inod )
191 correct_elements = 1;
192 else
193 correct_elements = 0;
194 }
195 if ( distance<EPS_COORD && correct_elements ) {
196 max_element++;
197 el[0] = -CONTACTSPRING;
198 el[1] = inod;
199 el[2] = jnod;
200 length = 3;
201 db( ELEMENT, max_element, el, ddum, length,
202 VERSION_NORMAL, PUT );
203 length = 1;
204 db( ELEMENT_GROUP, max_element, &element_group, ddum, length,
205 VERSION_NORMAL, PUT );
206 length = 1;
207 db( ELEMENT_MACRO_GENERATE, max_element, &icontrol,
208 ddum, length, VERSION_NORMAL, PUT );
209 db( ELEMENT_DOF, max_element, idum, tmp_element_dof, mnolnuknwn, VERSION_NORMAL, PUT );
210 db( ELEMENT_DOF_INITIALISED, max_element, &zero, ddum, length, VERSION_NORMAL, PUT );
211 db( NONLOCAL_ELEMENT_INFO, max_element, idum, dworknei, length_nei, VERSION_NORMAL, PUT );
212 }
213 }
214 n++;
215 }
216 }
217 }
218 delete[] tmp_element_dof;
219 delete[] dworknei;
220 delete[] in_geometry_list;
221 if ( control_mesh_generate_contactspring_element_specified ) {
222 delete[] node_element_inod;
223 delete[] node_element_jnod;
224 }
225
226 mesh_has_changed( VERSION_NORMAL );
227 if ( swit ) pri( "Out routine GENERATE_SPRING." );
228 }
229
230 }
231
generate_beam_truss(long int icontrol,long int task)232 void generate_beam_truss( long int icontrol, long int task )
233
234 {
235 long int jn=0, inod=0, jnod=0, max_node_old=0, max_node=0, max_element=0,
236 element_group=0, in_geometry=0, igenerated=0, ngenerated=0, mgenerated=0,
237 length_node_node=0, already_generated=0, swit=0, length=0, loose=-NO, ldum=0,
238 node_macro_generate=0, length_macro=0, idum[1], control_mesh_generate[3],
239 geometry_entity[2], el[1+MNOL], macro[DATA_ITEM_SIZE],
240 *node_node=NULL, *in_geometry_list=0,
241 *generated_list=NULL, *new_node_list=NULL;
242 double rdum=0., ddum[MDIM], coord[MDIM], node_dof[MUKNWN];
243 long int zero=0, mnolnuknwn=npointmax*nuknwn, length_nei=1+npointmax*ndim+npointmax+2;
244 double *tmp_element_dof=NULL, *dworknei=NULL;
245 tmp_element_dof = get_new_dbl(mnolnuknwn);
246 dworknei = get_new_dbl(length_nei);
247 array_set(dworknei, 0, length_nei);
248
249 if ( task==TRUSS ) {
250 if ( db_active_index(CONTROL_MESH_GENERATE_TRUSS,icontrol,VERSION_NORMAL) )
251 db( CONTROL_MESH_GENERATE_TRUSS, icontrol, control_mesh_generate, ddum,
252 ldum, VERSION_NORMAL, GET );
253 else
254 return;
255 }
256 else if ( task==TRUSSBEAM ) {
257 if ( db_active_index(CONTROL_MESH_GENERATE_TRUSSBEAM,icontrol,VERSION_NORMAL) )
258 db( CONTROL_MESH_GENERATE_TRUSSBEAM, icontrol, control_mesh_generate, ddum,
259 ldum, VERSION_NORMAL, GET );
260 else
261 return;
262 }
263 else {
264 assert( task==BEAM );
265 if ( db_active_index(CONTROL_MESH_GENERATE_BEAM,icontrol,VERSION_NORMAL) )
266 db( CONTROL_MESH_GENERATE_BEAM, icontrol, control_mesh_generate, ddum,
267 ldum, VERSION_NORMAL, GET );
268 else
269 return;
270 }
271
272 swit = set_swit(-1,-1,"generate_beam_truss");
273 if ( swit ) pri( "In routine GENERATE_BEAM_TRUSS." );
274
275 db( CONTROL_MESH_GENERATE_TRUSS_BEAM_LOOSE, icontrol, &loose,
276 ddum, ldum, VERSION_NORMAL, GET_IF_EXISTS );
277 db( CONTROL_MESH_GENERATE_TRUSS_BEAM_MACRO, icontrol, macro,
278 ddum, length_macro, VERSION_NORMAL, GET_IF_EXISTS );
279
280 db_highest_index( ELEMENT, max_element, VERSION_NORMAL );
281 db_max_index( NODE_START_REFINED, max_node_old, VERSION_NORMAL, GET );
282
283 element_group = control_mesh_generate[0];
284 array_move( &control_mesh_generate[1], geometry_entity, 2 );
285
286 length = db_data_length(NODE_NODE);
287 node_node = get_new_int(length);
288
289 // list for nodes in geometry
290 in_geometry_list = get_new_int(1+max_node_old);
291 array_set( in_geometry_list, 0, (1+max_node_old) );
292
293 // list for generated beams/trusses,
294 mgenerated = 5*ndim*(1+max_node_old);
295 generated_list = get_new_int(mgenerated*2);
296 array_set( generated_list, -1, (mgenerated*2) );
297
298 // list for new node numbers (for generate with contact spring)
299 new_node_list = get_new_int(1+max_node_old);
300 array_set( new_node_list, -1, (1+max_node_old) );
301
302 for ( inod=0; inod<=max_node_old; inod++ ) {
303 if ( db_active_index( NODE_START_REFINED, inod, VERSION_NORMAL ) ) {
304 geometry( inod, ddum, geometry_entity, in_geometry, rdum, ddum, rdum,
305 ddum, NODE_START_REFINED, PROJECT_EXACT, VERSION_NORMAL );
306 if ( in_geometry ) in_geometry_list[inod] = 1;
307 }
308 }
309
310 if ( db_active_index( NODE, 0, VERSION_NORMAL ) ) {
311 pri( "Error: node number 0 not allowed if you generate trusses, beams, or so." );
312 exit(TN_EXIT_STATUS);
313 }
314
315 max_node = max_node_old;
316 for ( inod=0; inod<=max_node_old; inod++ ) {
317 if ( db_active_index( NODE_NODE, inod, VERSION_NORMAL ) ) {
318 if ( in_geometry_list[inod] ) {
319 node_macro_generate = -ALL;
320 db( NODE_MACRO_GENERATE, inod, &node_macro_generate, ddum, ldum, VERSION_NORMAL, GET_IF_EXISTS );
321 if ( length_macro==0 || array_member(macro,node_macro_generate,length_macro,ldum) ) {
322 db( NODE_NODE, inod, node_node, ddum, length_node_node, VERSION_NORMAL, GET );
323 for ( jn=0; jn<length_node_node; jn++ ) {
324 jnod = node_node[jn];
325 if ( jnod>=0 ) {
326 if ( in_geometry_list[jnod] ) {
327 node_macro_generate = -ALL;
328 db( NODE_MACRO_GENERATE, jnod, &node_macro_generate, ddum, ldum,
329 VERSION_NORMAL, GET_IF_EXISTS );
330 if ( length_macro==0 || array_member(macro,node_macro_generate,length_macro,ldum) ) {
331 already_generated = 0;
332 for ( igenerated=0; igenerated<ngenerated; igenerated++ ) {
333 if ( ( generated_list[igenerated*2+0]==inod &&
334 generated_list[igenerated*2+1]==jnod ) ||
335 ( generated_list[igenerated*2+0]==jnod &&
336 generated_list[igenerated*2+1]==inod ) )
337 already_generated = 1;
338 }
339 if ( !already_generated ) {
340 ngenerated++;
341 if ( ngenerated>mgenerated ) {
342 pri( "Error: mgenerated too small in routine generate_beam_truss. ");
343 exit(TN_EXIT_STATUS );
344 }
345 generated_list[(ngenerated-1)*2+0]=inod;
346 generated_list[(ngenerated-1)*2+1]=jnod;
347 if ( task==TRUSS )
348 el[0] = -TRUSS;
349 else if ( task==TRUSSBEAM )
350 el[0] = -TRUSSBEAM;
351 else {
352 assert( task==BEAM );
353 el[0] = -BEAM;
354 }
355 if ( loose==-YES ) {
356 // generate beam / truss
357 if ( new_node_list[inod]>=0 ) {
358 el[1] = new_node_list[inod];
359 }
360 else {
361 max_node++;
362 el[1] = max_node;
363 new_node_list[inod] = max_node;
364 db( NODE, inod, idum, coord, ldum, VERSION_NORMAL, GET );
365 db( NODE, max_node, idum, coord, ldum, VERSION_NORMAL, PUT );
366 db( NODE_START_REFINED, inod, idum, coord, ldum, VERSION_NORMAL, GET );
367 db( NODE_START_REFINED, max_node, idum, coord, ldum, VERSION_NORMAL, PUT );
368 length = 1; db( NODE_MACRO_GENERATE, max_node, &icontrol, ddum, length, VERSION_NORMAL, PUT );
369 db( NODE_DOF, inod, idum, node_dof, ldum, VERSION_NORMAL, GET );
370 db( NODE_DOF, max_node, idum, node_dof, ldum, VERSION_NORMAL, PUT );
371 db( NODE_DOF_START_REFINED, inod, idum, node_dof, ldum, VERSION_NORMAL, GET );
372 db( NODE_DOF_START_REFINED, max_node, idum, node_dof, ldum, VERSION_NORMAL, PUT );
373 }
374 if ( new_node_list[jnod]>=0 ) {
375 el[2] = new_node_list[jnod];
376 }
377 else {
378 max_node++;
379 el[2] = max_node;
380 new_node_list[jnod] = max_node;
381 db( NODE, jnod, idum, coord, ldum, VERSION_NORMAL, GET );
382 db( NODE, max_node, idum, coord, ldum, VERSION_NORMAL, PUT );
383 db( NODE_START_REFINED, jnod, idum, coord, ldum, VERSION_NORMAL, GET );
384 db( NODE_START_REFINED, max_node, idum, coord, ldum, VERSION_NORMAL, PUT );
385 length = 1; db( NODE_MACRO_GENERATE, max_node, &icontrol, ddum, length, VERSION_NORMAL, PUT );
386 db( NODE_DOF, jnod, idum, node_dof, ldum, VERSION_NORMAL, GET );
387 db( NODE_DOF, max_node, idum, node_dof, ldum, VERSION_NORMAL, PUT );
388 db( NODE_DOF_START_REFINED, jnod, idum, node_dof, ldum, VERSION_NORMAL, GET );
389 db( NODE_DOF_START_REFINED, max_node, idum, node_dof, ldum, VERSION_NORMAL, PUT );
390 }
391 length = 3;
392 max_element++;
393 db( ELEMENT, max_element, el, ddum, length, VERSION_NORMAL, PUT );
394 length = 1;
395 db( ELEMENT_GROUP, max_element, &element_group, ddum, length,
396 VERSION_NORMAL, PUT );
397 length = 1;
398 db( ELEMENT_MACRO_GENERATE, max_element, &icontrol, ddum, length,
399 VERSION_NORMAL, PUT );
400 db( ELEMENT_DOF, max_element, idum, tmp_element_dof, mnolnuknwn, VERSION_NORMAL, PUT );
401 db( ELEMENT_DOF_INITIALISED, max_element, &zero, ddum, length, VERSION_NORMAL, PUT );
402 db( NONLOCAL_ELEMENT_INFO, max_element, idum, dworknei, length_nei, VERSION_NORMAL, PUT );
403 }
404 else {
405 if ( task==TRUSS )
406 el[0] = -TRUSS;
407 else if ( task==TRUSSBEAM )
408 el[0] = -TRUSSBEAM;
409 else {
410 assert( task==BEAM );
411 el[0] = -BEAM;
412 }
413 el[1] = inod;
414 el[2] = jnod;
415 length = 3;
416 max_element++;
417 db( ELEMENT, max_element, el, ddum, length, VERSION_NORMAL, PUT );
418 length = 1;
419 db( ELEMENT_GROUP, max_element, &element_group, ddum, length,
420 VERSION_NORMAL, PUT );
421 length = 1;
422 db( ELEMENT_MACRO_GENERATE, max_element, &icontrol, ddum, length,
423 VERSION_NORMAL, PUT );
424 db( ELEMENT_DOF, max_element, idum, tmp_element_dof, mnolnuknwn, VERSION_NORMAL, PUT );
425 db( ELEMENT_DOF_INITIALISED, max_element, &zero, ddum, length, VERSION_NORMAL, PUT );
426 db( NONLOCAL_ELEMENT_INFO, max_element, idum, dworknei, length_nei, VERSION_NORMAL, PUT );
427 }
428 }
429 }
430 }
431 }
432 }
433 }
434 }
435 }
436 }
437
438 delete[] in_geometry_list;
439 delete[] generated_list;
440 delete[] new_node_list;
441 delete[] node_node;
442 delete[] tmp_element_dof;
443 delete[] dworknei;
444
445 mesh_has_changed( VERSION_NORMAL );
446 if ( swit ) pri( "Out routine GENERATE_BEAM_TRUSS." );
447
448 }
449