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