Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

ABAQUS SUBROUTINE DLOAD NOEL 1

Status
Not open for further replies.

keith11best

Civil/Environmental
Nov 8, 2016
15
0
0
NO
Hi everyone,

I am currently working on the ABAQUS SUBROUTINE to apply line loads on beam.

In my model, there are different parts, the part I am going to apply loads using 'DLOAD' has been defined with element number from 1 to 38, 39 to 76 and 77 to 114. I also have connector element and mass element in my model.

The element lode actually varies with my element number. So I am defining the 'F' in subroutine 'DLOAD' by the following

C I am defining load along Y direction
IF (JLTYP .EQ. 42) THEN
C nel is total element number
DO i=1,nel
C here NOEL is something I am really not following, according to manual, NOEL is element number, NPT is integration point number, but even if I define my element number from 1, it seems that ABAQUS always put the mass and connector elements ahead of beam element internally (I found this by write the NOEL out to .dat file)
IF (NOEL .EQ. (187+i) ) THEN
C here is the sentence that I give the calculated load to 'F' according to NOEL sequence, I add 'KF(i)=FY(i)' in order to monitor whether FY is transferred to 'F' as I desire. But it didn't!!!
F=FY(i)
KF(i)=FY(i)
END IF
END DO

Is there anyone who is familiar with this problem? Simply how to give my calculated load distribution to 'F' (which varyies at different element number) in 'DLOAD' subroutine?

Many thanks!
 
Replies continue below

Recommended for you

Hi Keith,

Are using part and assembly inputdeck structure or flat inputdeck structure?
With parts and assembly Abaqus use user and internal node/element numbers.
Abaqus before start analysis renumber whole model from user to internal ids.
In inputdeck you have user ids and in NOEL you have internal ids.
To obtain what internal id is used for specific user id you have tu use routine GETPARTINFO.
See: Abaqus User Subroutines Reference Guide, 2.1.5 Obtaining part information

With flat inputdeck all ids you use in inputdeck are treat as internal.

I do not get it why do you make a loop over element id?
DLOAD subroutine is called for each integration point separately, it means it can be called more than one time with the same element number.
If you have elements with reduced integration (one integration point) or you apply the same load for all integration points over one element you can just assume DLOAD is called once for each NOEL.

Example where load is two times element number:

1. Parts & assembly inputdeck
Code:
! apply load for specific load type only
if (JLTYP == 42) then

  ! what is my user id for current internal element id?
  iUserId = GETPARTINFO(NOEL, 1, CPNAME, LOCNUM, JRCD)

  ! apply load elements in range 1:114
  if (iUserId >= 1 .and. iUserId <=114)
    F = 2.0 * iUserId
  endif

endif

2. Flat inputdeck:
Code:
! apply load for specific load type only
if (JLTYP == 42) then

  ! apply load elements in range 1:114
  if (NOEL >= 1 .and. NOEL <=114)
    F = 2.0 * NOEL
  endif

endif

Why do you define your load as function of element number?
When you renumber model it will be not valid any more.

Regards,
Bartosz

VIM filetype plugin for Abaqus
 
Hi Akabarten,

Thanks so much for your detailed help!

Indeed, I was not using the part assembly for my input file, but the Flat inputdeck as you mentioned.

My input file related to DLOAD subroutine looks like this:
*Dload
**LOADELEM is the element set I need to apply loads
LOADELEM, PYNU
LOADELEM, PZNU

As I mentioned, I have 114 elements (elements set 'LOADELEM' I defined above). In my input file, their element number is from 1 to 114, but it seems that in the subroutine their NOEL starts from 188 to 301 as the internal element numbers, I used

WRITE(6,*) COORDS(1)
WRITE(6,*) COORDS(2)
WRITE(6,*) NOEL,NPT

in DLOAD subroutine to understand these numbers. What I assume is that I also have 117 mass elements and 70 connector elements (their element number in my input file is very very large). Probably ABAQUS has to prioritize these elements as smaller elements number anyways.

As to why I was using the loop to define 'F', the fact is that the element load (they are line loads on my beam) is the load I calculated (it is actually wind load, which I calculate for each element for each direction, for example, FY(i) is the i[sup]th[/sup] element line load at 'Y' direction. And these loads are varying at each elements (COORDS), but they are not function with COORDS). So I was using a loop to define the load for each element based on my understanding on 'NOEL', but apparently, it's not looping as I imagine. You can see part of the output from my .dat file. I don't understand why 188 appears 4 times? Was it caused by PYNU and PZNU?

1.47931823321338 !coordx for element number 188
-5.363854122647507E-007 !coordy for element number 188
188 1 !NOEL, NPT
5.52089080691544
-2.216298078161166E-007
188 2
1.47931823321338
-5.363854122647507E-007
188 1
5.52089080691544
-2.216298078161166E-007
188 2
9.53616193877294
-2.007170028612843E-007
189 1
16.4645141034704
-4.583377616445376E-007
189 2
9.53616193877294
-2.007170028612843E-007
189 1
16.4645141034704
-4.583377616445376E-007
189 2
21.5363971469254
-6.090482358758964E-007
190 1
28.4646871469945
-7.631761499255224E-007
190 2
21.5363971469254
-6.090482358758964E-007
190 1
28.4646871469945
-7.631761499255224E-007
190 2

Based on your experience, when ABAQUS transfer the NOEL to my subroutine, NOEL contains the whole model or only the 'LOADELEM' I defined here. Based on the output to my .dat file. It looks like only 'LOADELEM' is covered.


I hope I have explained my question clearly. Do you have any thoughts on how should I transfer my calculated load to 'F'? I am also not sure what's the difference between load on integration point or element? I am using B31 element, I have found material for integration node. Could you also help me a bit on this as well?

Thanks so much for your opinions!!!
 
Add
*Preprint, model=yes
into the input file and run a datacheck. Then you can find the internal numbering in the .dat file.

In A/CAE the option can be found in the job setting, where you can also specify the number of cpus and memory.
 
Hi Keith,

I don't understand why 188 appears 4 times? Was it caused by PYNU and PZNU?
Make sense for me. You can check it in easy way with "WRITE(6,*) NOEL,NPT,JLTYP".

when ABAQUS transfer the NOEL to my subroutine, NOEL contains the whole model or only the 'LOADELEM' I defined here
It transfers only elements with applied user load, so in your case all elements in LOADELEM elset.

If you are using flat inputdeck and still id of elements does not fit to inputdeck maybe Abaqus/Standard always make translation from user to internal ids.
Not sure here I do not work with Abaqus/Standard. Just follow Mustaine3 advise or:
Code:
call GETPARTINFO(NOEL, 1, CPNAME, LOCNUM, JRCD)
WRITE(6,*) NOEL,LCONUM

Regards,
Bartosz

VIM filetype plugin for Abaqus
 
Hi Bartosz,

Sorry for calling for Akabarten:)

Thanks for your suggestion, I tried to add 'JLTYP', and I think from .dat file, it's now associated with JLTYP. I also tried to use 'call GETPARTINFO', but abaqus keeps give me error, I am not able to get the NOEL from that.

Back to my question, do you think it's able to define my load to 'F' using a loop?
And what's the dimension for 'F'? If I have 114 elements for 'LOADELEM' and two integration points for each elment, the dimension for 'F' would be 228?

I'll try to define a FY with the dimension of 228 and use

[ignore]
IF (JLTYP .EQ. 42) THEN
F=FY
END IF
[/ignore]

I'll update you if it's ok.

Best,
Jungao
 
Hi Jungao,

To be honest I am still confuse about your load. I understand that each beam element will get different load.
The load is calculate outside DLOAD subroutine and next stored (by initialization and/or reading from external file) in FY array.
The FY array structures is:
FY(1) : load for element id 1
FY(2) : load for element id 2
FY(3) : load for element id 3
FY(i) : load for element id i

Am I right?

In this case it is enough
Code:
if (JLTYP == 42) then
  F = FY(NOEL)
endif
It is a nice idea but only if Abaqus doesn't change ids from user to internal and you control element numbering at pre-processor phase.
In other case we must know internal id for each user id.

I also tried to use 'call GETPARTINFO', but abaqus keeps give me error
What error? Did you add declaration statement
Code:
"CHARACTER*80 CPNAME"
By the way following syntax is incorrect, my bad, sorry.
Code:
iUserId = GETPARTINFO(NOEL, 1, CPNAME, LOCNUM, JRCD)
It should be
Code:
call GETPARTINFO(NOEL, 1, CPNAME, LOCNUM, JRCD)
iUserId = LOCNUM

Here you assign real value (name start with f letter) to integer value (k letter at the beginning).
It is a mistake unless you have explicit declaration for KF array.
Code:
KF(i)=FY(i)

If my understanding is right here you assign array (FY) to scalar (F), it is an error.
Code:
F=FY

And what's the dimension for 'F'?
Variable F is scalar real variable not an array. It has no dimension.
I am guessing you are asking about FY array. It must be number of elements in LOADELM or bigger.

Still I do not see any reason to make a loop. It make sense if your FY array keeps both element id and load value
(100, 1.0) : load of 1.0 for element id 100
(150, 2.0) : load of 2.0 for element id 150
(175, 3.0) : load of 3.0 for element id 175

Code:
! declaration block
parameter (iMaxSize = 114)
dimension FY(iMaxSize,2)

! find load value for current element
do i = 1, iMaxSize, 1
  if (FY(i,1) == NOEL) then
    F=FY(i,2) ! assign load value
    exit      ! do not search more, stop loop
  endif
enddo

Regards,
Bartosz

VIM filetype plugin for Abaqus
 
Hi Bartosz,

Thanks for your detailed instruction.

I have now output the element number using
Code:
call GETPARTINFO(NOEL, 1, CPNAME, LOCNUM, JRCD) 
iUserId = LOCNUM 
WRITE(6,*) CPNAME,NOEL,NPT,KINC,iUserId

The output looks like:
PART-1-1
188 1 1 1
PART-1-1
188 2 1 1
PART-1-1
189 1 1 2
PART-1-1
189 2 1 2
PART-1-1
190 1 1 3
PART-1-1
190 2 1 3
PART-1-1
191 1 1 4
PART-1-1
191 2 1 4
......

I have also attached the .dat file for your information, I am now only apply load for 38 elements for simplicity. (my dynamic total time is 0.01s, and time step is fixed to 0.01s, so there is only one timestep for my dynamic analysis, but the .dat file has much more information on NOEL, seems like repeated, I don't understand why...)

Your understanding on my loading FY is correct! It's FY(i) means the load for ith element.

As you mentioned,
Variable F is scalar real variable not an array. It has no dimension. I am guessing you are asking about FY array. It must be number of elements in LOADELM or bigger. Still I do not see any reason to make a loop. It make sense if your FY array keeps both element id and load value (100, 1.0) : load of 1.0 for element id 100 (150, 2.0) : load of 2.0 for element id 150 (175, 3.0) : load of 3.0 for element id 175
I suppose when ABAQUS call the subroutine DLOAD, it's actually looping in main function ABAQUS to define F for each element integration point (the size of the loop is (element number*integration number), correct? I think based on my .dat file, there are two integration points for each element.
Then, when I pass the value from array FY(i) to scalar F, the size of FY should also be (element number*integration number)? And F is in fact the load at each integration point? The looping sequence should be
NOEL, NPT
188, 1
188, 2
189,1
189,2
...

Is this understanding correct?
If yes, then
Code:
 if (JLTYP == 42) then 
 F = FY(NOEL) (total dimension of F should be 2*element number? Should I define FY as FY(odd number)=element load, FY(even number)=element load)
 endif

Code:
! declaration block
parameter (iMaxSize = 114) 
dimension FY(iMaxSize,2)

! find load value for current element
do i = 1, iMaxSize, 1
  if (FY(i,1) == NOEL) then
    F=FY(i,2) ! assign load value
    exit      ! do not search more, stop loop
  endif
enddo
If I am using the above alternative code, the effect of NPT is already considered, right?

Best,
Jungao

 
Hi Jungao,

>>> I have also attached the .dat file for your information
There is no attachment.

>>> I suppose when ABAQUS call the subroutine DLOAD, it's actually looping in main function ABAQUS to define F for each element integration point
Yes.

>>> the size of the loop is (element number*integration number)
It always depend on element types used in DLOAD. I think in your case your are right (element number*integration number).

>>> If I am using the above alternative code, the effect of NPT is already considered, right?
In these examples one and the same value will be applied for all integration points of specific element.
Is this a problem for you? Do you have need to apply different load for different integration points of one element?

Regards,
Bartosz

VIM filetype plugin for Abaqus
 
Hi Bartosz,

Sorry, it seems that I haven't upload the .dat file successfully.
I think I have fixed the problem.

I am using the following to define 'F'. I have double the size of FY (I define FFY as FFY(odd number)=element load, FFY(even number)=element load, same for FFZ below)
Code:
       IF (JLTYP .EQ. 42) THEN
           IF (NPT==1) THEN
               F = FFY(2*(NOEL-187)-1)
               WRITE(6,*) NOEL,NPT,F
           ELSE IF (NPT==2) THEN
               F = FFY(2*(NOEL-187))
               WRITE(6,*) NOEL,NPT,F
           END IF


      ELSE IF (JLTYP .EQ. 43) THEN 
           IF (NPT==1) THEN
               F = FFZ(2*(NOEL-187)-1)
               WRITE(6,*) NOEL,NPT,F
           ELSE IF (NPT==2) THEN
               F = FFZ(2*(NOEL-187))
               WRITE(6,*) NOEL,NPT,F
           END IF 
        END IF

Based on the output .dat file, F has been well defined from FY values. It's good new.
Thanks so much for your detailed explanation! I may trouble you if I have further problems.

I am also planning to work on UEL to define some added damping and stiffness for my beam model for next step.

Best,
Jungao
 
Hi Jungao

It is good to hear that it is starting to work as you expecting.

One advice from my side. You really should not depend on "187 offset" between user and internal ids.
It's probably true only for this one model, or maybe not. It is high likely with different Abaqus version/number of CPUS/processor architecture internal id will be different.
There is reason why developer created GETPARTINFO routine. It is only good way to check node/element ids.

If you are using different load values for integration point why not use two dimensional array.
Then you do not have deal with odd and even ids for 1st and 2nd NPT.

Code:
dimension FY(nr_of_elems, nr_intPoints)
dimension FZ(nr_of_elems, nr_intPoints)

! get user id
call GETPARTINFO(NOEL, 1, CPNAME, LOCNUM, JRCD) 

if (JLTYP == 42) then 
  F=FY(LOCNUM, NPT)   
elseif (JLTYP == 43) then
  F=FZ(LOCNUM, NPT)
endif

Regards,
Bartosz


VIM filetype plugin for Abaqus
 
Hi Bartosz,

Thanks for your advice!

It's a great idea:) I'll update them.

A next step for me right away is to actually update my element load for each time step.
In fact, 'F' in my case is also depending on the motion of the element as well (F is related to element displacement and velocity).
So my next step is to use URDFIL to output the element motion results and store them for next step calculation. 'DLOAD' can read the data stored by 'URDFIL' from last time step.

Or alternatively, in my i[sup]th[/sup] time step:
I should firstly read element motion from (i-1)[sup]th[/sup] time step using 'ORDFIL', and these information can be used by subroutine DLOAD to define 'F' for my current time step. I am not sure about the calling sequence for ABAQUS between 'URDFIL' and 'DLOAD', if 'URDFIL' can be called earlier, then I can use COMMON BLOCK to define those element motions and can be used by 'DLOAD' without file write and read. This could save some calculating time, I suppose.

Do you have some knowledge on this topic as well?

Best,
Jungao


 
Hi Jungao,

I have never used URDFIL subroutine so I know nothing about it.
But as long you are ok with displacement and velocity of integration points you can evaluate them in DLOAD.

Code:
! keep values in memory
save rPrevCOORDx
save rPrevCOORDy
save rPrevCOORDz
save rPrevTIME

! disp = position(i) - position(i-1)
rUx = COORDS(1) - rPrevCOORDx
rUy = COORDS(2) - rPrevCOORDy
rUz = COORDS(3) - rPrevCOORDz

! vel = disp / (time(i)-time(i-1))
rTimeDelta = TIME(1) - rPrevTime
rVx = rUx / rTimeDelta
rVy = rUy / rTimeDelta
rVz = rUz / rTimeDelta

! store current positions and time to use in next increment
rPrevCOORDx = COORD3(1)
rPrevCOORDy = COORD3(2)
rPrevCOORDz = COORD3(3)
rPrevTime = TIME(1)

Did you think about using UAMP subroutine instead DLOAD?
I understand it can be a problem with applying load over many elements but you have nice access to outputs in UAMP with sensor outputs.

Regards,
Bartosz

VIM filetype plugin for Abaqus
 
Hi Bartosz,

It's another great suggestion!

Code:
! keep values in memory
save rPrevCOORDx
save rPrevCOORDy
save rPrevCOORDz
save rPrevTIME

[b]Is it correct that we need to declare 'save' in the beginning, then they are saved as global variables
 (can be transferred to the subroutine for next time increment?)[/b]

! disp = position(i) - position(i-1)
rUx = COORDS(1) - rPrevCOORDx
rUy = COORDS(2) - rPrevCOORDy
rUz = COORDS(3) - rPrevCOORDz

! vel = disp / (time(i)-time(i-1))
rTimeDelta = TIME(1) - rPrevTime
rVx = rUx / rTimeDelta
rVy = rUy / rTimeDelta
rVz = rUz / rTimeDelta

! store current positions and time to use in next increment
rPrevCOORDx = COORD3(1)
rPrevCOORDy = COORD3(2)
rPrevCOORDz = COORD3(3)
rPrevTime = TIME(1)

With this method, then I should actually judge whether KINC==1.
If yes, all pre values are 0, otherwise, using the code you provided. Is this correct?


Did you think about using UAMP subroutine instead DLOAD?
I understand it can be a problem with applying load over many elements but you have nice access to outputs in UAMP with sensor outputs.
I am quite new to ABAQUS, subroutine and FORTRAN (started about 2 months ago), so I have limited knowledge of the huge capability of ABAQUS.
I just browsed UAMP, is it more like a subroutine to define a time-varying value?
For my case, I am more concerned about the load distribution on different elements. (The loads are dependent my defined parameters, which are the wind velocity distribution at different element locations and the element motions, I call them motion-dependent forces). So I think DLOAD is more straightforward.

Another thought is the wind field I defined, now they are stored outside as a .dat file, I read them in subroutine DLOAD and then use them and motions from last time step to calculate the loads for next time step. But these wind field data is also quite large, every step I have to open and read. Do you think I should define them as array in my subroutine to save time? Or do you have better idea for this perhaps?

Thanks!

Jungao
 
Hi Jungao

>>> Is it correct that we need to declare 'save' in the beginning, then they are saved as global variables
By default all variables used in subroutine are not controlled after call.
It means part of memory where your variable is stored can be overwrite by any other program or Abagus itself after DLOAD call.
You will lose data saved there. SAVE statement force that this particular part of memory will be protect from overwrite after DLOAD end.
It is FORTRAN feature not Abaqus. The problem is that SAVE statement workaround for simulations with 1CPU.
If you run such subroutine with many CPUS and distributed parallel memory you will come into a troubles.
To overcame this many of Abaqus subroutines have so called state variable.
Usually is an array which you can use to save variables values between calls. It is controlled by Abaqus so it works in any case.
Unfortunately DLOAD does not support this feature.

>>> With this method, then I should actually judge whether KINC==1.
>>> If yes, all pre values are 0, otherwise, using the code you provided.
Yes, you are right you should initialise prev values to zero or with DATA statement or check for KINC=1.
I would not believe that Abaqus will initialize them to zero by itself.

>>> Do you think I should define them as array in my subroutine to save time? Or do you have better idea for this perhaps?
Read it only in first inc, put it into memory with SAVE statement and read it later from memory not from external file.

Regards,
Bartosz

VIM filetype plugin for Abaqus
 
Hi Bartosz,

Thanks for all your help and good instruction for this topic.
My subroutine is now working.

I am moving to the next step (using UEL to add extra damping and stiffness to my model).
Do you have any reference material in mind that maybe helpful for my next step?


Thanks in advance!
 
Status
Not open for further replies.
Back
Top