# Cyclic loading in PFC-2D

**URL:** <https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348>\
**Category:** PFC\
**Created:** [March 9, 2026, 8:53am UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348 "2026-03-09T08:53:00Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mujeeb](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@Mujeeb](https://forum.itascainternational.com/u/Mujeeb)\
**Post date:** [March 9, 2026, 8:53am UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/1 "2026-03-09T08:53:00Z")

</div>

I am trying to apply cycling load to the top wall in a 2D biaxial test using the sinusoidal function (q = q0_sinwt)._ From the literature, different values for omega (w) have been suggested, among which I selected 10\*pi as an initial guess. The value of ‘qo’ has been obtained from the cyclic stress ratio (CSR) and confining stress (CSR = qo/2\*confining stress). I defined a fish function that applies a force on the top wall based on the value of q and the width of the samples, and to maintain the undrained condition, I found the velocity of the top wall, and, accordingly, the lateral wall velocities were adjusted. However, once the simlation starts ‘q’ does not follow the sinusoidal variation. I have a attached the code block for your reference.

[csr = 0.1]  
[q\_amp = 2\*_p0_\*csr]  
[omg = 10\*math.pi]

fish define cyclic\_loading  
whilestepping

local t = mech.time.total  
global q\_target = q\_amp \* math.sin(omg\*t)  
global Fy = -q\_target \* wlx

command  
wall servo activate on force-y [Fy] velocity-max 1.0 range set name ‘vesselTop’  
endcommand  
local vy = wall.vel.y(wp\_top)  
local vx = -(wlx/wly)_0.5_vy

command  
wall attribute velocity-x [vx] range set name ‘vesselRight’  
wall attribute velocity-x [-vx] range set name ‘vesselLeft’  
endcommand

end

---

<div class="post-metadata">

**Author:** ![jcoulibaly](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.itascainternational.com/jcoulibaly/32/1681_2.png) [@jcoulibaly](https://forum.itascainternational.com/u/jcoulibaly)\
**Post date:** [March 9, 2026, 7:15pm UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/2 "2026-03-09T19:15:03Z")

</div>

Hello Mujeeb,

Thank you for sharing your issue.

Please consider providing a Minimum Working Example (MWE) that can be run and replicated when requesting help; that greatly simplifies troubleshooting and helps getting you to a resolution faster. From this FISH snippet alone, it is difficult to guide you.

You might be able to draw inspiration from the [Probing a Granular Specimen](https://docs.itascasoftware.com/itasca960/pfc/docproject/source/manual/examples/examples/granular/granular.html?highlight=wp_top) example which perform similar loading to what you are trying to achieve.

Please let me know if that helps. If not, please share a complete MWE and we will help you troubleshoot it.

Best,  
Jibril B. Coulibaly

---

<div class="post-metadata">

**Author:** ![Mujeeb](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@Mujeeb](https://forum.itascainternational.com/u/Mujeeb)\
**Post date:** [March 10, 2026, 3:48am UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/3 "2026-03-10T03:48:52Z")

</div>

Thanks for your reference.

Can you please share the email ID so that I can send the project file including dat files in RAR format

---

<div class="post-metadata">

**Author:** ![Mujeeb](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@Mujeeb](https://forum.itascainternational.com/u/Mujeeb)\
**Post date:** [March 10, 2026, 10:10am UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/4 "2026-03-10T10:10:44Z")

</div>

Dear Sir  
Please find the dat files attached to this email:

(Attachment StrainUtilities.p2fis is missing)

> **(attachments)**
>
> [psd.fis](https://forum.itascainternational.com/uploads/short-url/jc0OL2e8RhAai47ywQyHqGf6t13.fis) (10.7 KB)  
> [Step2\_Compact.dat](https://forum.itascainternational.com/uploads/short-url/1IrDcuZhZ2hX1FMwhFQMvX9bAlk.dat) (3.87 KB)  
> [psd1.fis](https://forum.itascainternational.com/uploads/short-url/pQZyXBdYUcsHQgEeEqplgRLwwHO.fis) (4.38 KB)  
> [Step1\_Sample.dat](https://forum.itascainternational.com/uploads/short-url/83TmuZwdrQGJDJokega2006QkNi.dat) (3.47 KB)  
> [mem\_sing.fis](https://forum.itascainternational.com/uploads/short-url/vPrc9rU1tFsWkbSgsdskImYknMB.fis) (2.35 KB)  
> [Stress1.fis](https://forum.itascainternational.com/uploads/short-url/vsuF4ma517jdicW5KQXEG5tb9jO.fis) (1.77 KB)  
> [Stress\_Cyclic.dat](https://forum.itascainternational.com/uploads/short-url/lj0lEslJhjAfEPxCYGA5JTZJSuT.dat) (3.31 KB)

---

<div class="post-metadata">

**Author:** ![Mujeeb](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@Mujeeb](https://forum.itascainternational.com/u/Mujeeb)\
**Post date:** [March 10, 2026, 10:34am UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/5 "2026-03-10T10:34:16Z")

</div>

> **(attachments)**
>
> [StrainUtilities.fis](https://forum.itascainternational.com/uploads/short-url/cqxcuNxAZLyCyvbSU01TI4YWqqJ.fis) (1.55 KB)

---

<div class="post-metadata">

**Author:** ![jcoulibaly](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.itascainternational.com/jcoulibaly/32/1681_2.png) [@jcoulibaly](https://forum.itascainternational.com/u/jcoulibaly)\
**Post date:** [March 10, 2026, 3:20pm UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/6 "2026-03-10T15:20:43Z")

</div>

Thank you for sharing these files.

As you pointed out, attachment `StrainUtilities.p2fis` is missing, would you be able to share this file with me on the forum?

One more question I forgot to ask: which exact version of PFC are you running?

Thank you

---

<div class="post-metadata">

**Author:** ![Mujeeb](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@Mujeeb](https://forum.itascainternational.com/u/Mujeeb)\
**Post date:** [March 10, 2026, 3:42pm UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/7 "2026-03-10T15:42:29Z")

</div>

Dear Sir  
I have sent the required file.  
Currently we are using PFC9

---

<div class="post-metadata">

**Author:** ![jcoulibaly](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.itascainternational.com/jcoulibaly/32/1681_2.png) [@jcoulibaly](https://forum.itascainternational.com/u/jcoulibaly)\
**Post date:** [March 10, 2026, 4:40pm UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/8 "2026-03-10T16:40:26Z")

</div>

The data file `Step1_sample.dat` calls for `program call 'StrainUtilities.p2fis' suppress` line 5. I had to change the extension of the file you shared from `StrainUtilities.p2fis` to `StrainUtilities.fis`.

The data file `Step1_sample.dat` calls for `call 'm3_sphere.fis'` on line 95. This file was not shared and the script cannot run past this point.

Please make sure to provide _all_ information and files necessary to run the program. If the issue cannot be replicated, it cannot be resolved.

Which _exact_ version of PFC9 are you using? e.g., 9.00.184, 9.6.45?

Thank you

---

<div class="post-metadata">

**Author:** ![Mujeeb](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@Mujeeb](https://forum.itascainternational.com/u/Mujeeb)\
**Post date:** [March 10, 2026, 4:50pm UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/9 "2026-03-10T16:50:47Z")

</div>

Sir, you can comment on the line that calls m3\_sphere.fis.

PFC 9.00.180

---

<div class="post-metadata">

**Author:** ![jcoulibaly](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.itascainternational.com/jcoulibaly/32/1681_2.png) [@jcoulibaly](https://forum.itascainternational.com/u/jcoulibaly)\
**Post date:** [March 10, 2026, 8:36pm UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/10 "2026-03-10T20:36:07Z")

</div>

Hi Mujeeb,

I ran the simulation and I think some of your issues may be coming from the callbacks.  
In the `Stress_cyclic.dat` file, running the `fish list callbacks` command just before solving for the model line 143 prints the following:

```plaintext
Position Function 
-------- --------
-1.000000000000000 cyclic_loading 
1.000000000000000 wsxx 
1.000000000000000 wsyy 
1.000000000000000 poro_sample 
1.000000000000000 average_ratio 
1.000000000000000 cyclic_loading 
9.000000000000000 servo_walls

```

- the `cycling_loading` function appears twice, at position -1.0 and 1.0. This is due to the `whilestepping` FISH function, which automatically inserts a callback to the function that call `whilestepping` at position -1.0. This command is deprecated and only conserved for backward compatibility; I recommand you remove it from this script and replace it with a regular fish callback in your future workflows.
- the `servo_walls` callback defined line 64-69 of `Step2_Contact.dat` is still active and overwrites the values of [Fy] in the `wall servo` command line 120 of `Stress_cyclic.dat`. I suggest this callback be removed `fish callback remove servo_walls`. Just like you did the first time during compaction, the command `wall servo` line 120 can be called once directly in the input file, and a FISH function is only used to modify the target force of the servo, as opposed to calling the servo command each step in the callback. Same thing with the left / right wall velocities.
- please note that `global t = mech.time.total` gives the current global time, which includes prior time spent compacting the sample, so that the sinusoid `global q_target = q_amp * math.cos(omg*t)` will start with a value that is not the current force at the end of compaction and might be different from what you want. This sinusoid will also change sign, so that the servo wall will try to impose a tensile force, which is not feasible with cohesionless particles; you may want to revisit this loading.

An updated script would look similar to the snippet below (to be modified according to your precise needs):

```auto
wall servo activate off range set name 'vesselTop' ...
                            set name 'vesselBottom' union 
wall servo activate off range set name 'vesselRight' ...
                            set name 'vesselLeft' union 

; remove servo_walls callback from compaction phase
fish callback remove servo_walls

[csr = 0.02]
[q_amp = 2*p0*csr]
[omg = 100*math.pi]

; Activate new servo wall on top wall. force [0.0] will be overwritten in [cyclic_loading] fish callback
wall servo activate on force-y [0.0] velocity-max 1.0 range set name 'vesselTop'

fish define cyclic_loading
; No whilestepping !

  ; TO BE MODIFIED ACCORDING TO YOUR NEEDS
  global t = mech.time.total
  
  ; sinusoidal deviatoric stress
  ; TO BE MODIFIED ACCORDING TO YOUR NEEDS
  global q_target = q_amp * math.cos(omg*t)

  ; convert stress to force
  global Fy = -q_target * wlx

  wall.servo.force.y(wp_top) = Fy
  
  ; constant volume
  local vy = wall.vel.y(wp_top)
  local vx = -(wlx/wly)*0.5*vy
  
  wall.vel.x(wp_right) = vx
  wall.vel.x(wp_left) = -vx

end

fish callback add cyclic_loading 9.0 ; MODIFIED FROM 1.0 TO 9.0
```

---

<div class="post-metadata">

**Author:** ![Mujeeb](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@Mujeeb](https://forum.itascainternational.com/u/Mujeeb)\
**Post date:** [March 15, 2026, 6:05pm UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/11 "2026-03-15T18:05:10Z")

</div>

I tried the above code, but every time its applying tensile forces on the sample. i tried changing the sign of Fy but it doesnot work for me.

---

<div class="post-metadata">

**Author:** ![Mujeeb](https://avatars.discourse-cdn.com/v4/letter/m/5f8ce5/32.png) [@Mujeeb](https://forum.itascainternational.com/u/Mujeeb)\
**Post date:** [March 17, 2026, 6:11pm UTC](https://forum.itascainternational.com/t/cyclic-loading-in-pfc-2d/2348/12 "2026-03-17T18:11:25Z")

</div>

[csr = 0.05] ; cyclic stress ratio  
[freq = 1]  
[servo\_gain = 1e-8]  
[q\_amp = 2_p0_csr]  
[t0 = mech.time.total]

fish define cyclic\_stress\_loading

```auto
local t = mech.time.total - t0

; target cyclic deviator stress
global q_target = 2*csr * p0 * math.sin(2.0*math.pi*freq*t)

; current deviator stress
global q_curr = wsyy - wsxx

; stress error
local err = q_target - q_curr

; axial velocity from servo
local vy = servo_gain * err

wall.vel.y(wp_top) = -vy
wall.vel.y(wp_bot) = vy

; constant volume condition
local vx = wall.vel.y(wp_top) * wlx / wly

wall.vel.x(wp_left) = vx
wall.vel.x(wp_right) = -vx

```

end

Can we modify the loading function like this??
