Previous | TableOfContents | Next |
The picture shows how Impact is structured. Impact is strictly object oriented in its design and I will use quite a few of the terms in the coming explanation. To appreciate the terms of object oriented programming, please read any book on the subject. Have a look in the Literature section for recommendation.
The elements and the nodes have each got their own class. Since there can be several types of elements, the element class is a superclass and it is also abstract which it acts as "format" for how a subclass should be written, which methods it should have etc. The element super class also contains some methods which are general and usable by all the element classes.
Impact is the main class. All it does is to immediately initiate an instance of the class smack and then it tells that instance to initiate, solve and postprocess the problem. Smack also includes a large array of nodes and elements which in fact is the actual model. When asked to solve the problem, it runs down these arrays and tells each element to update itself, over and over again.
Another important class is the material class. Since there can be several different types of models for a material, this is a superclass and then there are several subclasses. Right now, there are two material models available. One for pure elastic materials and one elasto-plastic materials (materials which are elastic to a point and then acts as gum beyond that point).
A model also contains constraints, forces and boundary conditions. Each of these have their own class and each element which has forces defined on it, knows about that by having a handle to the respective constraint etc.
Each element also knows about which nodes it has so that it can feed it's mass and forces to the nodes when asked to.
Finally, the reader class handles the reading of indata files (where the problem is defined) and the writer class handles the writing of the result files. Both are super classes in order to allow for several different indata and outdata file formats. This allows Impact to be compatible with other programs such as LS-Dyna and Radioss in the future.
The Impact class is the main class of the program. It is here the program starts and the following happens:
In the future, something like a command centre can designed in this class, creating a nice user interface. The possibility of initiating several solutions running in parallel is also easily accomplished. Just create several objects from the Smack class!
The Smack class is the centre of Impact. Here, the model is stored in two large arrays. One array for the Elements in the model and one array for the Nodes.
In addition, a number of smaller arrays are also used to store the Loads, Constraints and Materials that are defined in the problem indata file.
In short, an object created from the Smack class will do the following:
The reader class is the abstract parent class for different file translators. The challenge with structuring Impact was to figure out a good way of separating the input file format from the rest of the program. This was the result.
The reader class (or rather any chosen subclass) have two main tasks:
These tasks mean that the reader class must be able to interpret the indata file in terms of grammar and words.
Imagine now, that the reader class reads a typical indata file. A problem was that if the reader class must be able to know all the parameters that a certain element needs (for example), read these, generate the corresponding element object and then feed that object with all the data from the file, this means that the programmer must go in the the reader class and change when he/she adds a new element class or changes a class.
It is more attractive if the reader class can be independent from the element class. The solution used in Impact is that part of the interpreter is actually included into the element class, namely the part that reads the element parameters. The reader class just feeds the element with the actual indata file line where the parameters are written and the element does the rest.
You can read more about this solution in the element chapter
The writer class is the mother class of all the different writer classes. Each subclass provides a different output format.
A writer object is created at the start of the solution run and it is then called every time that Impact wants to print to an outdata file. This can happen several times during a solution. The writer class then walks through the database of elements and nodes and asks each of them to write their status.
An equal challenge as for the reader class is present here regarding being able to add new element classes without having to go into the writer class and change. The solution is the same, namely that the writer class asks the element object to print it's own line of outdata (in the right format), which is then directly written to the outdata file. All the preparation is made inside the element itself.
Due to how the outdata file is structured, the method that writes the data in the element is somewhat complex. The writer calls the same method several times, depending on if it wants the element to write data for a header or for another location in the outdata file. This is accomplished using control codes and is more explained in the element chapter.
This layout means that the element class needs to have one method for each new reader class (output file format), but since the amount of file formats are significantly less than the amount of element types, this is feasible.
The element class has been carefully designed to be self containing and easy to expand. The problem when writing a program is usually that when a programmer wants to add another feature (such as a new element type), it also means digging around in a lot of code which is indirectly related to the new element type.
The benefit of Impact is that this is not the case here. The programmer only needs to consider the following:
Once that is decided, the programmer is then free to add the new element along the lines described later in this manual. The basic method is to add a new subclass to the existing abstract class "Element" and then fill that new subclass with code.
When Impact is run and a number of elements are read in from the input file, a corresponding number of element objects are created. One object for each element.
The object will get a "memory" where it remembers which nodes it has attached to it, which material it is made of and so on.
If we stop a bit at the material "memory", I'd like to explain a little bit more in detail how it is handled. Some material laws need a memory in itself. This is the case since once some deformation has been made, a permanent deformation remains after unloading. This phenomenon means that the element (and material law) needs to remember how much it has been loaded in the past to accurately model the permanent deformation.
How to solve this? Well, the solution is quite simple. Once the element object has been created, a local internal material object is created which is based on the material law that the element is supposed to use. One can then think of the element object actually encapsulating it's own material object.
From here on, the element object talks only to it's own material object and since the material object keeps track on where it has been, the element object also has a memory of how much it has deformed.
A Solution run in Impact basically means that the solution loop (which is located inside smack), runs down a list of element objects and tell each of them to:
Since the element knows about its nodes and has a local material law to talk to, everything can be handled inside the element.
The purpose of the abstract element class (encircled) is threefold:
Each element class interprets its own indata. This means that the programmer does not need to change the reader or the writer class when adding a new element class. This is handled by the actual element class itself.
More details about this comes later in the chapter about how to add an element
A model consists of elements and nodes. The Node class defines the nodes behaviour.
In explicit codes, nodes are a bit extra important since the elements really only provide forces that act on the nodes.
All the mass of the elements are moved out into the nodes at the start of the solution process (initialization) and from there on, the simple formula of A=F/M is used to calculate the acceleration resulting from the forces put on the nodes by the elements.
The only thing the node has to do really is to be able to calculate it's acceleration, velocity and position in space and to accept forces and mass from the elements.
In the future, contact intelligence will also be built into the nodes.
As mentioned before, the node class is used by the reader class to create one node object for each node defined in the indata file. The node object is then fed some indata like its position in space and any constraints that might be applied on it.
The Load class is more or less a container for data regarding the different load cases that can be applied to elements and nodes.
In the start of a run, the indata file is scanned for load sets. For each load set, a load object is created and fed with the corresponding data (example Fx = 5 kN).
Each element or node which uses this load set, then has a handle to load object and can ask it about which loads that is applied. This is used especially by the nodes to figure out which loads that has to be added before it updates it's position.
The setup for the Constraint class is quite similar to the load class.
In the start of a run, the indata file is scanned for constraint sets. For each constraint set, a constraint object is created and fed with the corresponding data (example Ax = 5 m/s2).
Each element or node which uses this constraint set, then has a handle to it and can ask it about which constraints that are applied. This is used especially by the nodes to figure out which constraints that has to be applied before and after it has updated it's position.
There can be several different types of constraints. Therefore the constraint class is a superclass and there are different subclasses. Examples include the standard BoundaryCondition and RigidBody.
The controlset class is a special creature. It contains all the different control parameters that can be used to control the solution of a problem. Examples of such are:
At the start of a run, the indata file is read (by the reader) and a controlset object is created and fed with all the control data. Note that there can only be one control set object for each solution.
The controlset object is used by the smack object to control the solution. The main solver routine inside smack asks the control object about all the things in the list above so that the solution is performed correctly.
This class is the abstract "mother" class for all the different material laws that can be defined. The basic function of a material law is to calculate stresses from a given strain matrix and a given strain increment (also in a matrix format).
For a purely elastic material law, this is quite simple. Stress = Young's_modulus * strain, if we think one dimensional. When we move into elasto-plastic material laws, life becomes a little bit more complicated, but the basic principle remains. Return a stress, given a set of strains.
For reasons described in the element class, a local material object is created and embedded into each element object that is created. This material object is then "alive" throughout the whole solution and is having a frequent communication with its "mother" element, all the time answering the same question (about the stress).
The purpose with the abstract material class (encircled) is threefold:
At the current state of writing, there are only two material subclasses defined. One elastic material law and one elasto-plastic.
Each material law class interprets its own indata. This means that the programmer does not need to change the reader or the writer class when adding a new material law class. This is handled by the actual material class itself. More about this can be read in the chapter about how to add a material law sub class
The tracker class has been carefully designed to be self containing and easy to expand. The problem when writing a program is usually that when a programmer wants to add another feature (such as a new tracker type), it also means digging around in a lot of code which is indirectly related to the new tracker type.
The benefit of Impact is that this is not the case here. The programmer only needs to consider which input syntax the new tracker should use. Once that is decided, the programmer is then free to add the new tracker along the lines described later in this manual. The basic method is to add a new subclass to the existing abstract class "tracker" and then fill that new subclass with code.
When Impact is run and a number of trackers are read in from the input file, a corresponding number of tracker objects are created. One object for each tracker.
The object will get a "memory" where it remembers which nodes or elements it should read results from and so on.
A Solution run in Impact basically means that the solution loop (which is located inside smack), runs down a list of tracker objects and tell each of them to:
Since the tracker knows about its nodes, everything can be handled inside the tracker.
The purpose with the abstract tracker class is threefold:
Each tracker class interprets its own indata. This means that the programmer does not need to change the reader or the writer class when adding a new tracker class. This is handled by the actual tracker class itself.
More details about this comes later in the chapter about how to add an tracker
The TrackWriter class is the mother class of all the different TrackWriter classes. Each subclass provides a different output format. An example of such a subclass is the GidTrackWriter class which prints results so that they can be read by the GID pre- and postprocessor.
A trackwriter object is created at the start of the solution run and it is then called every time that Impact wants to print to an outdata file. This can happen several times during a solution. The TrackWriter class then walks through the database of elements and nodes and asks each of them to write their status.
An equal challenge as for the reader class is present here regarding being able to add new element classes without having to go into the trackwriter class and change. The solution is the same, namely that the trackwriter class asks the element object to print it's own line of outdata (in the right format), which is then directly written to the outdata file. All the preparation is made inside the element itself.
Due to how the outdata file is structured, the method that writes the data in the element is somewhat complex. The trackwriter calls the same method several times, depending on if it wants the element to write data for a header or for another location in the outdata file. This is accomplished using control codes and is more explained in the Tracker chapter.
This layout means that the tracker class needs to have one method for each new TrackWriter class (output file format), but since the amount of file formats are significantly less than the amount of tracker types, this is feasible.
Previous | TableOfContents | Next |