Thomas Wölfers Baustatik-Blog

Thomas Wölfers Baustatik Blog

Auf jeden Fall ansehen: Machine Architecture and You


Sehr interessantes Video von Herb Sutter: Machine Architecture and You

Man braucht ein bisschen Zeit, das Video dauert etwa 2 Stunden. Zusätzlich zum Video gibts auch einen Link zu einem PDF mit den Slides. Ich empfehle, die Slides als erster runterzuladen und parallel zum Video anzusehen, denn im Video selbst sind die nicht besonders gut zu lesen.


6502


Kein Kommentar. (Oder doch einer: JavaScript? Mal im Ernst - JavaScript ?)


Ein ganz einfaches Makro


Weil ich heute sowas gebraucht habe: Dieses Makro ändert die Fenstergröße des "Baustatik" Fensters auf eine Größe von 1024x768 Pixel:

using System;
using System.Drawing;
using DIE.Framework.ApplicationModell.Commands;

namespace MeineMakros
{
 public class resize : UserCommandBase
 {
  public resize() : base(@"resize", @"Ändert die Fenstergröße")
  {
  }
  
  public override void Execute(IExecuteCommandContext context)
  {
     context.MainWindow.Size = new Size(1024,768);
  }
 }
}


Codekana für Visual Studio: Erstes Release


Codekana für Visual Studio ist nun im ersten Release verfügbar. Das Ding kostet etwa 30 Euro - und ich kann es nur empfehlen: Weiss schon gar nicht mehr, wie ich ohne die Codekana-Erweiterungen leben konnte. (Achso: Es gibt auch eine 30-Tage-Testversion...)


Der Fall mit der langen Berechnungszeit


Heute ist mir eine Datei untergekommen, bei der die Rechenzeit doch eher im unbrauchbaren Bereich lag: Das erzeugen des Netzes alleine brauchte fast 2 Stunden - damit kann man natürlich nicht vernünftig arbeiten. Beim System handelte es sich um eine Bodenplatte von etwa 100 x 30 m, die mit relativ vielen Einzellasten belastet war - außerdem waren ein paar Wände definiert.

Insgesamt gab es etwa 3600 Einzeleinwirkungen auf der Bodenplatte - und nach ein paar näheren Untersuchungen waren die es auch, die sich als das Problem herausstellten: Die Lasten waren als Knotenlasten und nicht als Faltwerkselement-Einzeleinwirkung definiert. Prinzipiell sollte es egal sein, welche der beiden Einwirkungsarten man verwenden - von der Performance her ist es aber so, das die deutlich besser wird, wenn man die Last als Faltwerkselement-Einzeleinwirkung definiert: In diesem Fall ist nämlich die zugehörige Platte schon bekannt und muss nicht erst ermittelt werden.

(Unabhängig davon ist das aktuelle Performance-Verhalten so nicht angebracht: Das werden wir auf jeden Fall nochmal näher untersuchen und verbessern.)

Die Lösung des Performance-Problems lag dann darin, das einfach alle Knoteneinwirkungen und Faltwerkselement-Einwirkungen "umgebaut" werden mussten. Man muss also die eine Einwirkung löschen, und dafür eine andere anlegen. Was kein Problem wäre - würde es sich nicht um 3600 Stück davon handeln. Die Lösung: Das folgende Makro. (Man erkennt schnell die Ähnlichkeit mit dem von gestern...:-) )


   IShell shell = context.TargetDocument.FindObject("NameDerPLatte", typeof(Shell)) as IShell;

   IDocObjectCollection loads = context.TargetDocument.GetObjects(typeof(INodeLoad));

   foreach (INodeLoad load in loads)
   {
      if( load.Lcs == LocalCoordinateSystem.Unit())
      {
         ShellSingleLoad newLoad = ShellSingleLoad.CreateNamed(context.TargetDocument);

         newLoad.ObjectName = load.ObjectName;
         newLoad.Loadcase = load.Loadcase;
         newLoad.LoadType = ShellSingleLoadTypes.Global;
         newLoad.SizeX = load.SizeX;
         newLoad.SizeY = load.SizeY;
         newLoad.SizeZ = load.SizeZ;
         newLoad.SizeXX = load.SizeXX;
         newLoad.SizeYY = load.SizeYY;
         newLoad.SizeZZ = load.SizeZZ;
         newLoad.Comment = load.Comment;
         newLoad.Node = load.Node;
         newLoad.Shell = shell;

         context.TargetDocument.RemoveObject(load);
         context.TargetDocument.AddObject(newLoad);
      }
   }

 


Beispielmakro: Stäbe zu Unterzügen


Vorab:

Makros in Baustatik
Erste Dokumentation für Baustatik-Makros

Es gibt Fälle, in denen man vorhandene Stäbe in Unterzüge umwandeln will - und zumindest zur Zeit liefern wir dafür keine fertige Funktion mit. Als Makro ist die Sache aber relativ einfach zu haben: Hier ein Makro, das genau diese Funktion erfüllt - zusammen mit ein paar Anmerkungen.

using System;
using DIE.Framework.ApplicationModell.Commands;
using DIE.Applications.Faltwerk.Objects.Beams;
using DIE.Applications.Faltwerk.Objects.BindingBeams;
using DIE.Framework.ObjectModell;

namespace MeineMakros
{
    public class stab2unterzug : UserCommandBase
    {
      // Initialisierung des Makrobefehls.
        public stab2unterzug() : base(@"stab2unterzug", @"übersetzt stäbe in unterzüge")
        {
        }
        
        // Einsprungsfunktion des Makros
        public override void Execute(IExecuteCommandContext context)
        {
            // alle balken holen (alternativ könnte man auch nur die
            // holen, die momentan ausgewäht sind.)
            IDocObjectCollection beams = context.TargetDocument.GetObjects( typeof(Beam));
            
            // über alle balken iterieren.
            foreach( IBeam beam in beams)
            {
                // für jeden balken einen neuen unterzug anlegen.
                BindingBeam bindingBeam = new BindingBeam();
                
                // all eigenschaften übertragen. die findet man in der
                // referenz-dokumentation (baustatik.chm) für die Objekte unter
                // https://blogs.die.de/tw/PermaLink.aspx?guid=d0d11a5f-9a4c-403b-8e48-1176fdf4b57b
                bindingBeam.ObjectName = beam.ObjectName;
                bindingBeam.StartProfile = beam.StartProfile;
                bindingBeam.EndProfile = beam.EndProfile;
                bindingBeam.Material = beam.Material;
                bindingBeam.DesignParameter = beam.DesignParameter;
                bindingBeam.AdditionalProfileRotation = beam.AdditionalProfileRotation;
                bindingBeam.Anfangsknoten = beam.Anfangsknoten;
                bindingBeam.Endknoten = beam.Endknoten;
                bindingBeam.RotLocalX = beam.RotLocalX;
                bindingBeam.StartJoint = beam.StartJoint;
                bindingBeam.EndJoint = beam.EndJoint;
                
                // den nicht mehr benötigten Stab löschen
                context.TargetDocument.RemoveObject( beam);
                
                // den neuen unterzug ins dokument tun
                context.TargetDocument.AddObject( bindingBeam);
            }
        }
    }
}

Wie man sieht: Auch wenn eine bestimmte Funktion nicht von uns mitgeliefert wird - mit wenigen Zeilen kann man sowas leicht selbst nachrüsten. :-)

 

stab2unterzug.cs (1.91 KB)

Managed Code: 32bit vs. 64 bit


Ich hatte am Freitag ein paar Worte zu unserer Statiksoftware in Bezug auf 32 und 64bit sowie Multicore Systeme gesagt. Das führte zu einer Rückfrage, ob ich darüber nicht einen Artikel für eine Zeitschrift verfassen wollte. Nun schreibe ich ja in der Tat hin- und wieder mal solche Fachbeiträge - in diesem Fall glaube ich aber, das das Thema einfach nicht genug für einen solchen Text hergibt. Für einen kurzen Blogeintrag ist es aber vielleicht ausreichend... Mal sehen.

Zunächst mal ist die erste Frage: Wodurch wird die Anwendung 32- oder 64bittig? Da gibt es ein paar Fälle... Im Visual Studio kann man unter den Projekteigenschaften bei "Build" eine Platform Target einstellen. Dort gibt es 3 Optionen, und zwar x86, x64 und "Any CPU". Stellt man die Option auf x86, wird Code für x86 generiert: Der läuft dann sowohl auf 32bit als auch auf 64bit Maschinen als 32bit Code. Stellt man die Option auf x64, dann läuft das Resultat als 64bitter nur noch auf 64bit Maschinen. Stellt man die Option hingegen auf "Any CPU", dann läuft das Resultat auf 64bit Maschinen als 64bitter und auf 32bit Systemen als 32bitter.

Wenn zum Projekt mehrere Assemblies gehören, dann legt die ladende Assembly (also die mit dem Eintrittspunkt ins Programm) fest, ob die Sache 32bittig oder 64bittig wird. Im Wesentlichen kann man also immer die Default-Option "Any CPU" eingeschaltet lassen, und hat dann nie Ärger, egal wie die Zielplatform aussieht.

Dazu gibt es eine Ausnahme, und die tritt dann in Kraft, wenn man im Projekt 32bit Code verwenden muss. Dabei ist mit "muss" gemeint: Man hat entweder eine 3rd Party Bibliothek die es nur in 32bit Geschmacksrichtung gibt, oder aber man hat eigenen Code den man noch nicht umstellen kann oder will. In diesem Fall bleibt einem nichts anderes übrig, als den Eintrittspunkt als "x86" zu übersetzen, und damit eine komplett 32bittige Anwendung zu erzeugen.

Warum überhaupt x64? Gute Frage - auf die ich aber leider keine einfache Antwort kenne. Der wesentliche Vorteil von x64 ist der, das man einen deutlich größeren Adressraum hat. Und zwar einen, der in der Theorie 16 Exabyte unterstützt (was ziemlich viel ist), in der Praxis bei Win64 aber nur 16 Terabyte umfasst (was im Vergleich zu den 4GB bei Win32 auch ziemlich viel ist.). Davon hat man aber nur was, wenn man a) diese Speichermenge auch braucht und b) über Hardware verfügt wo man auch tatsächlich mehr als 4GB reinstecken kann.

Dabei gibt es durchaus Anwendungen auf die a) zutrifft - nicht zuletzt kümmere ich mich um so Kram, weil einige unserer Programme gerne auch mal sehr viel Speicher verbrauchen (Handregel: Je größer das Gebäude das berechnet wird, um so mehr Speicher wird dafür benötigt :-)).

b) ist hingegen eine Sache, die sich wohl erst in nächster Zeit entwickeln wird: (Desktop) Motherboards in die tatsächlich mehr als 4 GB reingehen sind selten - und wenn, dann gehen auch nur 8 rein. (Zumindest habe ich keine anderen gefunden.). Das wird sich mittelfristig natürlich ändern, ist aber zumindest zur Zeit der Stand der Dinge.

Man kann auch ganz sicher Performance-Betrachtungen anstellen, bei denen rauskommt, das 64bit Programme schneller sind als 32bit Programm - aber das genaue Gegenteil geht mit Sicherheit auch. Ebenso kann man wohl Messungen machen, bei denen rauskommt das 64bit Programme größer sind als 32bit Programm (schließlich brauchen ja alle Pointer doppelt so viel Platz) - aber in Abhängigkeit vom Programm geht auch hier wohl das Gegenteil.

Im Wesentlichen läuft das für mich auf eines hinaus: Wenn man keine sehr speziellen Anforderungen hat (so wie wir mit dem massiven Speicherbedarf) und auch nicht an "altem" 32bit Code hängt - dann verwendet man am besten die Option "Any CPU" - denn die macht am wenigsten Ärger.

Apropos Ärger: Einen kleinen Haken hat die Sache schon. Wenn man Interop (PInvoke) verwendet, dann muss man sicherstellen, das die meist von Hand gebastelten Interfaces auch _wirklich_ stimmen - ansonsten funktionieren die hinterher nämlich nur auf ein 32bit Platform, aber nicht auf einer 64bit Platform. Oder natürlich umgekehrt. Hint: pinvoke.net ist dabei wirklich hilfreich.

Hilfreich zu lesen: Everything you need to know to start programming 64-bit Windows Systems.


Hello World in Xaml


Oliver hat Beispielcode für ein "Hello World" in seinem Blog. Naja - nett. Aber ganz ehrlich: In C war das einfacher....

void main() { printf("hello word"); }

Man kanns halt nicht allen recht machen... :-)


Studentenjob zu vergeben


Sie sind: Student oder Schüler und haben Spaß am programmieren? Dann passen Sie vielleicht zu uns - zumindest wenn Sie in München oder Umgebung leben, den der Job wäre in unserer Münchner Niederlassung. Interessiert? Dann einfach bei mir melden: tw@die.de