madil4 / awatif

The First Web-based Parametric Structural Engineering Platform

Home Page:https://awatif.co

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Baisc dynamic example

madil4 opened this issue · comments

The goal is to set up an architecture to handle dynamic simulation within Awatif. So, we will focus now on bar elements in 2D. In other iterations, we will expand to 3D bars and expose parameters for users to play with.

You can follow these guidelines if it makes sense to you but I would encourage you to improve it and make it better.

1- Setup the example: In /examples/basic-dynamic/main.ts:

const nodes = [
  [0, 0, 0],
  [2, 0, 0],
  [4, 0, 0],
];

const elements = [
  [0, 1],
  [1, 2],
];

const assignments = [
  {
    node: 0,
    support: [true, true, true],
  },
  {
    node: 1, // and 2 similarly
    force: [0, 0, -20], // gravity force computed for masses of 2 and acceleration of 9.81
  },
  {
    element: 0, // and 1 similarly
    elasticity: 1,
  },
];

const analysisResults = analyzeDynamically(nodes, elements, assignments, {
  time: 5,
  timeStep: 0.001,
});

app({ model: { nodes, elements, assignments, analysisResults } });

2- Write the dynamic algorithm: in /examples/basic-dynamic/analyzeDynamically.ts

export function analyzeDynamically(nodes, elements, assignments, config) {
  // run the dynamic loop here

  analysisResults = {
    1: [ // here is the frame/step number
      {
        node: 0,
        position: [0, 0, 0], // here is the new computed position 
      },
      {
        node: 2,
        position: [0, 0, 0],
      },
    ],
    2: [
      {
        node: 0,
        position: [0, 0, 0],
      },
      {
        node: 2,
        position: [0, 0, 0],
      },
    ],
  };
}

3- Add TimeLine component to App component: in /awatif-ui/src/App.ts

if (condition) TimeLine(modelState); // check if we have dynamic analysis results, if so, show the Timeline

4- Implement the Timeline component: in /awatif-ui/src/Timeline.ts

function TimeLine(modelState) {
  const frame = van.State(0); // the frame in consideration
  const isPlayed = false:

  // render the slider with vanjs rendering system instead of pure html and append it to body
  slider = input({ type: "range", min: "0", max: "100" });

  // change the frame state according to slider.value
  slider.oninput(() => {
    frame.val = slider.value;
  });

  // change nodes positions according to frame state
  van.derive(() => {
    modelState.val.nodes = modelState.val.analysisResults[frame.val].position;
  });

  // animate slider value
  setInterval(() => {
    if (isPlayed) slider.val = frame.val + 1; // this assumes the steps from the analysis results are incremented by 1
  }, 1000/30); // 30 fps, the animation is handled by the viewer, which is triggered when changing the position 
}