# Using abaqus umat from shared library

**URL:** <https://calculix.discourse.group/t/using-abaqus-umat-from-shared-library/2493>\
**Category:** Uncategorized\
**Created:** [December 5, 2024, 11:04am UTC](https://calculix.discourse.group/t/using-abaqus-umat-from-shared-library/2493 "2024-12-05T11:04:48Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![shroud](https://avatars.discourse-cdn.com/v4/letter/s/58956e/32.png) [@shroud](https://calculix.discourse.group/u/shroud)\
**Post date:** [December 5, 2024, 11:04am UTC](https://calculix.discourse.group/t/using-abaqus-umat-from-shared-library/2493/1 "2024-12-05T11:04:48Z")

</div>

I want to use abaqus umats from a shared library, but somehow it does not work. This is how I do it, according to the documentation:

**Create the shared library**  
This includes several files, where some utility subroutines and the umats are included.  
The Filename of the umat is for example umat\_abaqus\_lineartest.f90.  
I compile it using gfortran to a file libLIBNAME.so.  
The subroutine for the material behavior itself is only called lineartest, as this is how I understood it from the documentation.

**Calculix executable**  
I am using the Calculix executable which can be downloaded here: [FEA Cluster](https://www.feacluster.com/calculix.php)

**Calling the shared library**  
This is done in the inp file with

```auto
*MATERIAL, NAME=@ABAQUS_LIBNAME_LINEARTEST
*USER MATERIAL, CONSTANTS=2
...

```

Have I missed something, or is it meant to be that for one umat routine you have one shared library? This I can’t find in the documentation anywhere.

After trying to run it, it creates a file named WarnNodeMussMultiStage.nam with this content:

```auto
 *NSET,NSET=WarnNodeMultiStage

```

---

<div class="post-metadata">

**Author:** ![johanngil](https://avatars.discourse-cdn.com/v4/letter/j/779978/32.png) [@johanngil](https://calculix.discourse.group/u/johanngil)\
**Post date:** [December 5, 2024, 4:44pm UTC](https://calculix.discourse.group/t/using-abaqus-umat-from-shared-library/2493/2 "2024-12-05T16:44:02Z")

</div>

Using an existing executable only makes sense if that was compiled with the compiler option `-DCALCULIX_EXTERNAL_BEHAVIOURS_SUPPORT` (see [this thread](https://calculix.discourse.group/t/implementing-umat-using-shared-library/2441/5) on a similar recent discussion). Otherwise it won’t work. The mentioned thread further recommends to include the additional compiler option `-DCALCULIX_EXTERNAL_BEHAVIOUR_DEBUG` to better understand what is going on.

---

<div class="post-metadata">

**Author:** ![rsmith](https://yyz2.discourse-cdn.com/free1/user_avatar/calculix.discourse.group/rsmith/32/1684_2.png) [@rsmith](https://calculix.discourse.group/u/rsmith)\
**Post date:** [December 5, 2024, 6:08pm UTC](https://calculix.discourse.group/t/using-abaqus-umat-from-shared-library/2493/3 "2024-12-05T18:08:51Z")

</div>

> [@johanngil](#):
>
> Using an existing executable only makes sense if that was compiled with the compiler option `-DCALCULIX_EXTERNAL_BEHAVIOURS_SUPPORT`

And since this option is only used in `Makefile_MFront` and not in the other `Makefiles` that come with CalculiX, most existing executables will probably _not_ be built with external support.

Also keep in mind that this is a _potential_ security vulnerability. Especially when running a pre-built library.

---

<div class="post-metadata">

**Author:** ![shroud](https://avatars.discourse-cdn.com/v4/letter/s/58956e/32.png) [@shroud](https://calculix.discourse.group/u/shroud)\
**Post date:** [December 6, 2024, 7:33am UTC](https://calculix.discourse.group/t/using-abaqus-umat-from-shared-library/2493/4 "2024-12-06T07:33:59Z")

</div>

Thanks for the Replys.

I tried already to compile the executable with the compilerflag, but this gave me no result. Probably I added it not at the correct Makefile. I also tried using C for the umat, as this is mentioned as well in the documentation.

The Library is build by myself, so no malicious stuff will be in there.

---

<div class="post-metadata">

**Author:** ![rsmith](https://yyz2.discourse-cdn.com/free1/user_avatar/calculix.discourse.group/rsmith/32/1684_2.png) [@rsmith](https://calculix.discourse.group/u/rsmith)\
**Post date:** [December 6, 2024, 8:20am UTC](https://calculix.discourse.group/t/using-abaqus-umat-from-shared-library/2493/5 "2024-12-06T08:20:20Z")

</div>

> [@shroud](#):
>
> I also tried using C for the umat, as this is mentioned as well in the documentation.

If you write the `umat` in C, the name of the function in the object file will be different!

External functions written in Fortran have an underscore appended to the name, while those in C haven’t.

From the ccx source code:

In `umat_abaqus.f`:

```auto
      subroutine umat_abaqus(amat,iel,iint,kode,elconloc,emec,emec0,
     & beta,xokl,voj,xkl,vj,ithermal,t1l,dtime,time,ttime,
     & icmd,ielas,mi,nstate_,xstateini,xstate,stre,stiff,
     & iorien,pgauss,orab,istep,kinc,pnewdt,nmethod,iperturb)

```

In `pcgsolver.c`:

```auto
ITG cgsolver (double *A, double *x, double *b, ITG neq, ITG len, ITG *ia, 
               ITG *iz,double *eps, ITG *niter, ITG precFlg);
void PCG (double *A, double *x, double *b, ITG neq, ITG len, ITG *ia, 
          ITG *iz,double *eps, ITG *niter, ITG precFlg,
          double *rho, double *r, double *g, double *C, double *z);
void CG (double *A, double *x, double *b, ITG neq, ITG len, ITG *ia, 
         ITG *iz,double *eps, ITG *niter,double *r, double *p, double *z);
void Scaling (double *A, double *b, ITG neq, ITG *ia, ITG *iz, double *d);
void MatVecProduct (double *A, double *p, ITG neq, ITG *ia, ITG *iz, 
                    double *z);
void PreConditioning (double *A, ITG neq, ITG len, ITG *ia, ITG *iz, 
                      double alpha, ITG precFlg,double *C, ITG *ier);
void Mrhor (double *C, ITG neq, ITG *ia, ITG *iz, double *r, double *rho);
void InnerProduct (double *a, double *b, ITG n, double *Sum);

```

Using `nm` to look at the object files:

```auto
> nm --extern-only --defined-only umat_abaqus.o pcgsolver.o

umat_abaqus.o:
0000000000000000 T umat_abaqus_

pcgsolver.o:
0000000000000950 T CG
0000000000000910 T InnerProduct
0000000000000170 T MatVecProduct
00000000000003a0 T Mrhor
00000000000004d0 T PCG
0000000000000220 T PreConditioning
0000000000000000 T Scaling
0000000000000c20 T cgsolver

```

If you look in the file `external.c`, you will see in the function `calculix_registerExternalBehaviour` that it is looking for a symbol called `umat_` (so following the Fortran convention) in the shared library.

---

<div class="post-metadata">

**Author:** ![shroud](https://avatars.discourse-cdn.com/v4/letter/s/58956e/32.png) [@shroud](https://calculix.discourse.group/u/shroud)\
**Post date:** [January 6, 2025, 4:10pm UTC](https://calculix.discourse.group/t/using-abaqus-umat-from-shared-library/2493/6 "2025-01-06T16:10:43Z")

</div>

Thanks for the replies. I had to put it aside for a while for other projects, and got back to it the last days.  
But I must still miss something, as I can’t manage it to work. It loads the test problem but exits without any visible error or computations.

I compiled ccx myself, adding the compiler flags as mentioned above.

```auto
-DCALCULIX_EXTERNAL_BEHAVIOURS_SUPPORT

```

Is it possible to find out if this step was successful at all? Adding the debug flag results in the same console output during compilation.

Next, I have the umat. I tried naming it different, but as said by @rsmith `calculix_registerExternalBehaviour` looks for umat\_. I would assume naming the function simply `subroutine umat(..) .. end subroutine umat` is the way to go then? At least in the doc, it says the function is called with the third part of the material name. This would mean I have to name it `subroutine linel(..)...` for example, not umat. Both variants don’t seem to work for me.

The umat is written in free-format .f90 using the abaqus umat template. Could this cause the problem? In the doc, it is recommended to use 77 standard.

Next, I added the path variable

```auto
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/folder/with/.so

```

Double checked with `echo $LD_LIBRARY_PATH`. The library itself is stored in this case with libLINEARTEST.so. The lib is stripped by ccx, as I understood it in the source files.

Calling the external behaviour in the .inp looks as follows for a simple linear elastic test case:

```auto
*MATERIAL, NAME=@ABAQUSNL_LINEARTEST_LINEL
*USER MATERIAL,CONSTANTS=2
210000.0,0.3

```

However, trying different variations in the naming etc. has not resolved the problem. It feels like I am missing something obvious?

---

<div class="post-metadata">

**Author:** ![rsmith](https://yyz2.discourse-cdn.com/free1/user_avatar/calculix.discourse.group/rsmith/32/1684_2.png) [@rsmith](https://calculix.discourse.group/u/rsmith)\
**Post date:** [January 6, 2025, 6:52pm UTC](https://calculix.discourse.group/t/using-abaqus-umat-from-shared-library/2493/7 "2025-01-06T18:52:55Z")

</div>

> [@shroud](#):
>
> Is it possible to find out if this step was successful at all? Adding the debug flag results in the same console output during compilation.

If you also add `-DCALCULIX_EXTERNAL_BEHAVIOUR_DEBUG` you _should_ get extra messages when using external materials. See `external.c`.

> [@shroud](#):
>
> It feels like I am missing something obvious?

If I read the documentation correctly, your subroutine should be named `subroutine LINEL()` (upper case).  
To quote the documentation:

_The base name of the library and the name of the function must be upper-cased._

---

<div class="post-metadata">

**Author:** ![shroud](https://avatars.discourse-cdn.com/v4/letter/s/58956e/32.png) [@shroud](https://calculix.discourse.group/u/shroud)\
**Post date:** [January 13, 2025, 4:46pm UTC](https://calculix.discourse.group/t/using-abaqus-umat-from-shared-library/2493/8 "2025-01-13T16:46:32Z")

</div>

Turned out I did miss the obvious. At least it wasn’t for me before.

The following two things have to be considered:

- Add the compiler Flag to the C-flags, not the F-flags. Should be clear when the routines are written in C that are responsible for calling the library, I still missed it.
- In case of an undefined reference error, make sure to rerun the whole process. Only recompiling partially does not work.

Now, it actually tells me that it can not find the external library, which means it’s looking for it.

Thanks y’all for the support.

---

<div class="post-metadata">

**Author:** ![shroud](https://avatars.discourse-cdn.com/v4/letter/s/58956e/32.png) [@shroud](https://calculix.discourse.group/u/shroud)\
**Post date:** [January 14, 2025, 8:13am UTC](https://calculix.discourse.group/t/using-abaqus-umat-from-shared-library/2493/9 "2025-01-14T08:13:45Z")

</div>

Maybe I will add some more information on how to do it, as it looks to me there is quite a bit information out there which diverges from each other.

This should help to include Abaqus umat as a shared Library.

1. Create the umat in the Abaqus format. As a template, the file umat.f can be used. The documentation says at this point the following:

> A further drawback of using  
> shared libraries is that the behavior must be written in C or C++ and the name  
> of the functions implementing the behavior must be upper-case due to CalculiX  
> internal conventions.

The template is given in Fortran, I did it in Fortran and it works. As mentioned by @rsmith, this seems to be due to the headers of the function in Fortran and C have an underscore / no underscore.

1. Naming of the subroutine: Using Fortran, the name of the subroutine should be `subroutine UMAT(..)`. In external.c, the call to the external library is handled. As far as my knowledge goes, it seems that it is looking for a function name as well as umat\_ in the header of the shared library. Which points to the quote above, that C has to be used when the implementation goes with a different function name as above.  
Note that per library only one umat is possible, when the subroutine is named umat.

2. Compiling the umat: I use gfortran. For each library, a individual makefile is needed. This should be straight forward, but I will share mine:

```auto
# Define the Fortran compiler
FC = gfortran

# Define the compiler flags
FFLAGS = -Wall -O2 -fPIC -ffree-form

# Default target
$(SRC)/%.o: $(SRC)/%.f90
	$(FC) $(FFLAGS) -c $< -o $@

# Define the source files and the output shared library
FSRC = $(wildcard *.f90)
FLIB = libLINEARTEST.so
FOBJ = $(FSRC:.f90=.o)

# Rule to create the Fortran shared library
make: $(FLIB)

$(FLIB): $(FSRC)
	$(FC) -shared -o $@ $^

# Clean up
clean:
	rm -f $(FLIB) $(CLIB) $(FOBJ) $(COBJ)

```

1. Next, a ccx version with activated compiler flags is needed. Those have to be added to the C compiler, not fortran. This looks as follows. I think there are not mentioned in the documentation?

```auto
CFLAGS = -Wall -O2 -I ../../../SPOOLES.2.2 -DARCH="Linux" -DSPOOLES -DARPACK -DMATRIXSTORAGE -DNETWORKOUT -DCALCULIX_EXTERNAL_BEHAVIOURS_SUPPORT -DCALCULIX_EXTERNAL_BEHAVIOURS_DEBUG -fPIC -DPIC

```

Make sure to recompile clean when activating the flags, I missed it.

1. Make the Library available to ccx. This can either be done by placing the \*.so in the same folder as the ccx executable (works for me) or by editing LD\_LIBRARY\_PATH on unix, pointing to the library.

```auto
export $LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/folder/with/.so

```

1. Calling the user material in the input file: When the subroutine is named umat, it should be called with` @ABAQUSNL_LIBRARY`. I have not tested to implement it in C, it should be an additional `_FUNCTIONNAME`, according to external.c. It also needs to be mentioned that a preceding `lib` is omitted by calculix.

2. I used the source files from [FEA Cluster](https://www.feacluster.com/calculix.php) and edited the Perl installation script a little to accomodate for a seperate umat compilation and some QoL features to save time when compiling/ installing several umats into shared librarys.
