From 36a466198190e081e03edb9634104820a66a1c31 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Thu, 20 Jan 2005 01:25:50 +0000
Subject: [PATCH] Adding python solver interface from Carl Osterwisch
 <osterwischc@asme.org>.

The interface comes with a example python "solver" that converts an Abacus
result file (in CSV format) into Gmsh post-processing views. Very cool ;-)
Thanks Carl!
---
 TODO                             |   6 +-
 doc/CREDITS                      |   5 +-
 doc/texinfo/gmsh.texi            |  14 +-
 utils/solvers/python/Gmsh.py     | 210 ++++++++++++++++
 utils/solvers/python/postcsv.opt |  20 ++
 utils/solvers/python/postcsv.py  | 306 ++++++++++++++++++++++++
 utils/solvers/python/testcsv.csv | 200 ++++++++++++++++
 utils/solvers/python/testcsv.geo |  18 ++
 utils/solvers/python/testcsv.msh | 395 +++++++++++++++++++++++++++++++
 9 files changed, 1165 insertions(+), 9 deletions(-)
 create mode 100644 utils/solvers/python/Gmsh.py
 create mode 100644 utils/solvers/python/postcsv.opt
 create mode 100755 utils/solvers/python/postcsv.py
 create mode 100644 utils/solvers/python/testcsv.csv
 create mode 100644 utils/solvers/python/testcsv.geo
 create mode 100644 utils/solvers/python/testcsv.msh

diff --git a/TODO b/TODO
index 716c7ad401..91732a92c7 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-$Id: TODO,v 1.78 2005-01-14 22:53:20 geuzaine Exp $
+$Id: TODO,v 1.79 2005-01-20 01:25:49 geuzaine Exp $
 
 ********************************************************************
 
@@ -6,6 +6,10 @@ add GUI for the Layer stuff in Extrude commands
 
 ********************************************************************
 
+add vertex arrays for isolines in post-pro
+
+********************************************************************
+
 Labels:
 - add dynamic variables? E.g., if a string contains %string.string,
 replace it dynamically in Draw_Text2D/3D by calling
diff --git a/doc/CREDITS b/doc/CREDITS
index 4332081244..50efe68d7b 100644
--- a/doc/CREDITS
+++ b/doc/CREDITS
@@ -1,4 +1,4 @@
-$Id: CREDITS,v 1.24 2005-01-01 19:35:39 geuzaine Exp $
+$Id: CREDITS,v 1.25 2005-01-20 01:25:49 geuzaine Exp $
 
              Gmsh is copyright (C) 1997-2005
 
@@ -95,4 +95,5 @@ Jose Miguel Pasini <jmp84 at cornell.edu>, Philippe Lussou <plussou at
 necs.fr>, Jacques Kools <JKools at veeco.com>, Bayram Yenikaya
 <yenikaya at math.umn.edu>, Peter Hornby <p.hornby at arrc.csiro.au>,
 Krishna Mohan Gundu <gkmohan at gmail.com>, Christopher Stott
-<C.Stott@surrey.ac.uk>, Timmy Schumacher <Tim.Schumacher@colorado.edu>.
+<C.Stott@surrey.ac.uk>, Timmy Schumacher <Tim.Schumacher@colorado.edu>,
+Carl Osterwisch <osterwischc@asme.org>.
diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi
index 47e70000da..e6f06eaee9 100644
--- a/doc/texinfo/gmsh.texi
+++ b/doc/texinfo/gmsh.texi
@@ -1,5 +1,5 @@
 \input texinfo.tex @c -*-texinfo-*-
-@c $Id: gmsh.texi,v 1.169 2005-01-18 16:13:35 geuzaine Exp $
+@c $Id: gmsh.texi,v 1.170 2005-01-20 01:25:49 geuzaine Exp $
 @c
 @c Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 @c
@@ -404,11 +404,13 @@ evaluated at the center of its circumscribed circle/sphere.
 @node Solver, Post-processing, Mesh, Overview
 @section Solver: external solver interface
 
-External solvers can be interfaced with Gmsh through Unix sockets, which
-permits to easily launch external computations and to collect and exploit
-the simulation results within Gmsh's post-processing module. The default
-solver interfaced with Gmsh is GetDP
-(@uref{http://www.geuz.org/getdp/}).
+External solvers can be interfaced with Gmsh through Unix or TCP/IP sockets,
+which permits to easily launch external computations and to collect and
+exploit the simulation results within Gmsh's post-processing module. The
+default solver interfaced with Gmsh is GetDP
+(@uref{http://www.geuz.org/getdp/}). Small examples of solvers written in C,
+C++, Perl and Python are available in the source distribution (in the
+@file{utils/solvers/} directory).
 
 @c -------------------------------------------------------------------------
 @c Post-processing: scalar, vector and tensor field visualization
diff --git a/utils/solvers/python/Gmsh.py b/utils/solvers/python/Gmsh.py
new file mode 100644
index 0000000000..ccbe8ae6cc
--- /dev/null
+++ b/utils/solvers/python/Gmsh.py
@@ -0,0 +1,210 @@
+#!/usr/bin/env python
+"""Gmsh.py - Python module for interacting with the Gmsh pre/post processor.
+
+Module functions:
+    getopt() -- Parse command line options
+    send() -- Send a string to the Gmsh socket if open
+
+Included classes:
+    Client -- A class for maintaining socket communication with Gmsh.
+    Mesh -- A class for storing nodes and elements.
+
+Typical use:
+    import sys
+    import Gmsh
+    opt = Gmsh.getopt(sys.argv[1:])
+    if opt.has_key('--socket'):
+        c = Gmsh.Client(opt['--socket'])
+    Gmsh.send('Testing testing', Gmsh.INFO)
+
+Carl Osterwisch <osterwischc@asme.org>, January 2005
+"""
+
+import socket
+import struct
+import time
+import os
+import sys
+
+START    = 1
+STOP     = 2
+INFO     = 10
+WARNING  = 11
+ERROR    = 12
+PROGRESS = 13
+VIEW     = 20
+OPTION   = 100
+OPTION_1 = OPTION + 0
+OPTION_2 = OPTION + 1
+OPTION_3 = OPTION + 2
+OPTION_4 = OPTION + 3
+OPTION_5 = OPTION + 4
+
+# Module variable used to store the open communication socket with Gmsh
+sock = None
+
+def getopt(opts):
+    """Parse the given list (usually sys.argv) into a dict. 
+
+    This is a very crude function which scans for options of the form
+    ['-option=value'] and returns a dict of the form {'-option':'value'}.
+    """
+    options = {}
+    for o in opts:
+        s = o.split('=', 1)
+        if len(s) < 2:
+            if s[0].startswith('-'):
+                # Option with no value given.
+                options[s[0].lower()] = None
+            else:
+                # Value with no option given.
+                options[None] = s[0]
+        else:
+            # Assign the given value to the option.
+            options[s[0].lower()] = s[1]
+    return options
+
+def send(message, type=INFO):
+    """Send information to Gmsh using the open socket. 
+
+    Keyword arguments:
+    message -- the string message to send
+    type -- the type of message being sent (default INFO)
+
+    As of Gmsh version 1.56, type should be one of:
+    START STOP INFO WARNING ERROR PROGRESS VIEW OPTION 
+    OPTION_1 OPTION_2 OPTION_3 OPTION_4 OPTION_5 
+
+    If no socket has been opened (using a Gmsh.Client instance) then print the
+    string sys.stderr.
+    """
+    if sock:
+        sock.sendall(struct.pack('II', type, len(message)))
+        sock.sendall(message)
+    elif type is not PROGRESS:
+        print >>sys.stderr, message
+
+class Client:
+    """Initiate and maintain connection with Gmsh socket.
+    
+    Instance this class to open and initiate socket communication with Gmsh.
+    Communication will be automatically and gracefully terminated when the
+    instance is destroyed.  Only one instance should exist at a time.
+    """
+
+    def __init__(self, filename):
+        """Open and initiate connection to Gmsh socket.
+        
+        Keyword arguments:
+        filename -- the name of the Unix socket given by Gmsh
+            
+        Assigns the new socket to the module variable sock and sends the
+        process id to Gmsh to initiate the communication.
+        """
+        self.initialized = 0
+        global sock
+        if not sock:
+            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+            time.sleep(0.1)
+            sock.connect(filename)
+            send(str(os.getpid()), START)
+            self.initialized = 1
+        else:
+            send('Gmsh.sock already exists as'+sock.getsockname(), ERROR)
+
+    def __del__(self):
+        """Gracefully close communications upon destruction.
+        
+        Sends the STOP signal to Gmsh and closes the socket.
+        """
+        global sock
+        if self.initialized:
+            send('Done.', STOP)
+            sock.close()
+            sock = None
+
+class Mesh:
+    """This is a class for storing nodes and elements.
+
+    Members:
+    nodes -- A dict of the form { nodeID: [ xcoord, ycoord, zcoord] }
+    elements -- A dict of the form { elemID: (type, [tags], [nodeIDs]) }
+
+    Methods:
+    read(file) -- Parse a Gmsh version 1.0 or 2.0 mesh file
+    write(file) -- Output a Gmsh version 2.0 mesh file
+    """
+
+    def __init__(self):
+        self.nodes = {}
+        self.elements = {}
+
+    def read(self, mshfile):
+        """Read a Gmsh .msh file.
+        
+        Reads Gmsh format 1.0 and 2.0 mesh files, storing the nodes and
+        elements in the appropriate dicts.
+        """
+
+        readmode = 0
+        send('Reading %s'%mshfile.name)
+        for line in mshfile:
+            line = line.strip()
+            if line.startswith('$'):
+                if line == '$NOD' or line == '$Nodes':
+                    readmode = 1
+                elif line == '$ELM':
+                    readmode = 2
+                elif line == '$Elements':
+                    readmode = 3
+                else:
+                    readmode = 0
+            elif readmode:
+                columns = line.split()
+                if readmode == 1 and len(columns) == 4:
+                    # Version 1.0 or 2.0 Nodes
+                    try:
+                        self.nodes[int(columns[0])] = map(float, columns[1:])
+                    except ValueError:
+                        send('Node format error: '+line, ERROR)
+                        readmode = 0
+                elif readmode > 1 and len(columns) > 5:
+                    # Version 1.0 or 2.0 Elements 
+                    try:
+                        columns = map(int, columns)
+                    except ValueError:
+                        send('Element format error: '+line, ERROR)
+                        readmode = 0
+                    else:
+                        (id, type) = columns[0:2]
+                        if readmode == 2:
+                            # Version 1.0 Elements
+                            tags = columns[2:4]
+                            nodes = columns[5:]
+                        else:
+                            # Version 2.0 Elements
+                            ntags = columns[2]
+                            tags = columns[3:3+ntags]
+                            nodes = columns[3+ntags:]
+                        self.elements[id] = (type, tags, nodes)
+        send('  %d Nodes'%len(self.nodes))
+        send('  %d Elements'%len(self.elements))
+
+    def write(self, file):
+        """Dump the mesh out to a Gmsh 2.0 msh file."""
+        print >>file, '$MeshFormat\n2.0 0 8\n$EndMeshFormat'
+        print >>file, '$Nodes\n%d'%len(self.nodes)
+        for (id, coord) in self.nodes.items():
+            print >>file, id, ' '.join(map(str, coord))
+        print >>file, '$EndNodes'
+        print >>file, '$Elements\n%d'%len(self.elements)
+        for (id, elem) in self.elements.items():
+            (type, tags, nodes) = elem
+            print >>file, id, type, len(tags),
+            print >>file, ' '.join(map(str, tags)),
+            print >>file, ' '.join(map(str, nodes))
+        print >>file, '$EndElements'
+
+if __name__ == '__main__':
+    print __doc__
+
diff --git a/utils/solvers/python/postcsv.opt b/utils/solvers/python/postcsv.opt
new file mode 100644
index 0000000000..e2c89709ff
--- /dev/null
+++ b/utils/solvers/python/postcsv.opt
@@ -0,0 +1,20 @@
+// These options define 'postcsv.py' as the second solver in Gmsh's
+// solver module, under the name 'PostCSV'.
+Solver.Name1 = "PostCSV";
+Solver.Help1 = "A filter to read node or element 
+indexed, comma-separated-value results into Gmsh.
+Carl Osterwisch <osterwischc@asme.org>
+January 2005";
+Solver.Executable1 = "./postcsv.py";
+Solver.Extension1 = ".csv";
+Solver.MeshName1 = "";
+Solver.MeshCommand1 = "--mesh=%s";
+Solver.SocketCommand1 = "--socket=%s";
+Solver.NameCommand1 = "--results=%s";
+Solver.OptionCommand1 = "--options";
+Solver.FirstOption1 = "Option";
+Solver.FirstButton1 = "Import";
+Solver.FirstButtonCommand1 = "%s";
+Solver.ClientServer1 = 1;
+Solver.MergeViews1 = 1;
+Solver.PopupMessages1 = 1;
diff --git a/utils/solvers/python/postcsv.py b/utils/solvers/python/postcsv.py
new file mode 100755
index 0000000000..1e0d3eadec
--- /dev/null
+++ b/utils/solvers/python/postcsv.py
@@ -0,0 +1,306 @@
+#!/usr/bin/env python
+"""Convert csv finite element data into Gmsh pos format.
+
+Usage:
+    postcsv.py --mesh=gmshfile.msh --results=csvfile.csv [--average]
+
+If --average is specified, the data for each node ID and each element ID is
+averaged, otherwise repeated IDs are assumed to be new time steps.
+
+csvfile.csv is in the following format:
+    # comments start with #
+    # time step 1 nodal scalar and vector data
+    node, heading1, heading2
+    1, 132.5, .0032 .0012 .0011
+    2, 100.2, .0030 .0004 -.0120
+    3,  98.3, .0021 .0032 .0002
+    # time step 1 elemental scalar data
+    element, heading3
+    1, 32.63
+    2, 30.34
+    3, 21.32
+    # time step 2 nodal scalar and vector data
+    node, heading1, heading2
+    1, 232.5, .0022 .0022 .0031
+    2, 200.2, .0020 .0014 .0110
+    3,  68.3, .0011 .0022 .0012
+
+Carl Osterwisch <osterwischc@asme.org>, January 2005
+"""
+
+import Gmsh
+import os, sys, re
+
+class PostMesh(Gmsh.Mesh):
+    """Store and convert FE results into Gmsh pos format.
+
+    Extends the Gmsh.Mesh class by adding the following attributes:
+
+    Members:
+    dataTypes -- dict to convert data length into type (scalar, vector, ...)
+    elemTypes -- dict to convert mesh element type into pos element type
+    posTypes -- list in pos defined order of pos object types
+    nodalData -- dict of nodal results
+    elementData -- dict of element centroid results
+
+    Methods:
+    csvparse(csvfile): Read a comma-separated-value file of nodal results
+    makeviews(file): Write all the data out to a Gmsh pos file
+    saveview(posfile): Called by makeviews to output the data for one view
+    """
+    
+    # dataTypes is used to translate the length of a vector into its
+    # corresponding Gmsh type.
+    dataTypes = {1:'S', 3:'V', 9:'T'}
+
+    # elemTypes is used to convert from Gmsh mesh element type to Gmsh
+    # post-processing object type.
+    elemTypes = {1:'L', 2:'T', 3:'Q', 4:'S', 5:'H', 6:'I', 7:'Y'}
+
+    # postTypes lists the valid Gmsh post-processing objects (dataType-elemType
+    # combinations) in the order they are defined in the pos output file
+    # format.
+    postTypes = ['SP', 'VP', 'TP',
+              'SL', 'VL', 'TL',
+              'ST', 'VT', 'TT',
+              'SQ', 'VQ', 'TQ',
+              'SS', 'VS', 'TS',
+              'SH', 'VH', 'TH',
+              'SI', 'VI', 'TI',
+              'SY', 'VY', 'TY',
+              'T2', 'T2C', 'T3', 'T3C']
+
+    def __init__(self):
+        Gmsh.Mesh.__init__(self)
+
+        self.nodalData = {}
+        #{ viewName: { nodeID: [ [time1data], [time2data] ] } }
+
+        self.elementData = {}
+        #{ viewName: { elemID: [ [time1data], [time2data] ] } }
+
+        # Delimiter between columns in the data file
+        self.separator = '[,;]'
+
+    def csvparse(self, csvfile):
+        """Parse ascii file of results into elementData and nodeData.
+
+        The file should be comma separated columns with matching column
+        headings at the top.  The first column is assumed to be the node or
+        element number.  Each unique heading will generate a new view within
+        Gmsh.  Repeated headings will generate time steps for that view.
+        """
+
+        csv = re.compile('\s*' + self.separator + '\s*')
+        elem = re.compile('el', re.I)
+        datatype = self.nodalData
+
+        Gmsh.send('Parsing results from %s'%csvfile.name)
+        headings = []
+        for line in csvfile:
+            columns = csv.split(line.strip())
+            if len(columns) > 1:
+                # There are at least two columns.
+                linedata = []
+                try:
+                    id = int(columns[0])
+                    linedata = [map(float, column.split()) for column in columns[1:]]
+                except ValueError:
+                    # Assume this is a heading.
+                    headings = columns
+                    if elem.match(headings[0]):
+                        datatype = self.elementData
+                    else:
+                        datatype = self.nodalData
+                else:
+                    for viewName, viewData in zip(headings[1:], linedata):
+                        if not datatype.has_key(viewName):
+                            datatype[viewName] = {}
+                        if not datatype[viewName].has_key(id):
+                            datatype[viewName][id] = [ viewData ]
+                        else:
+                            datatype[viewName][id].append(viewData)
+        for (viewName, nodes) in self.nodalData.items():
+            Gmsh.send('  %s %d Nodal Results'%(viewName, len(nodes)))
+        for (viewName, elems) in self.elementData.items():
+            Gmsh.send('  %s %d Elemental Results'%(viewName, len(elems)))
+
+    def saveview(self, posfile, viewName=None, viewData=[]):
+        """Store the given viewData to the posfile.
+
+        If viewName is None it will output a header line to the file.
+        """
+        if not viewName:
+            print >>posfile, '$PostFormat\n1.2 0 8\n$EndPostFormat'
+        elif len(viewData):
+            Gmsh.send('  View '+viewName)
+
+            nts = len(viewData.values()[0][0][1][0])
+            print >>posfile, '$View\n%s %d'%(viewName, nts)
+
+            # Print section lengths.
+            for type in self.postTypes:
+                if viewData.has_key(type):
+                    print >>posfile, len(viewData[type]),
+                    Gmsh.send('    %s %d'%(type, len(viewData[type])))
+                else:
+                    print >>posfile, 0,
+
+            # Print dummy time-step values.
+            print >>posfile, '\n', ' '.join([str(i) for i in range(nts)])
+
+            # Print data.
+            for type in self.postTypes:
+                if viewData.has_key(type):
+                    for object in viewData[type]:
+                        for x in range(3):
+                            # Print the coordinates in the appropriate order.
+                            print >>posfile, ' '.join([str(i[x]) for i in object[0]])
+                        for timestep in range(nts):
+                            for nodalResult in object[1]:
+                                # Print the results.
+                                try:
+                                    print >>posfile, ' '.join([str(i) 
+                                            for i in nodalResult[timestep]])
+                                except IndexError:
+                                    Gmsh.send('      Insufficient time steps for all locations.', 
+                                            Gmsh.ERROR)
+                                    Gmsh.send('      Consider using --average if this is one time step.', 
+                                            Gmsh.ERROR)
+            print >>posfile, '$EndView'
+
+    def makeviews(self, file):
+        """Generate post-processing views for the results.
+
+        1. Loop through all defined elements and generate corresponding
+        post-processor objects for elements with nodalData.
+
+        2. Loop through all elementData and generate corresponding
+        post-processor objects.
+        """
+        self.saveview(file) # This just prints the header information
+
+        if len(self.nodalData):
+            Gmsh.send('Saving nodal results to '+file.name)
+            for viewName in self.nodalData.keys():
+                viewData = {}
+                for elem in self.elements.values():
+                    # Iterate over all defined elements.
+                    coord = []
+                    result = []
+                    for nid in elem[2]:
+                        # Gather node coordinates and results for this element.
+                        try:
+                            coord.append(self.nodes[nid])
+                        except KeyError:
+                            Gmsh.send('  Mesh is missing node %d'%nid, 
+                                    Gmsh.ERROR)
+                        try:
+                            result.append(self.nodalData[viewName][nid])
+                        except KeyError:
+                            pass
+                    if len(result) == len(coord) and \
+                            self.elemTypes.has_key(elem[0]):
+                        # There was data available at every node for this
+                        # element and this element has a corresponding
+                        # post-processing object.
+                        if self.dataTypes.has_key(len(result[0][0])):
+                            postType = self.dataTypes[len(result[0][0])] + \
+                                    self.elemTypes[elem[0]]
+                            if not viewData.has_key(postType):
+                                viewData[postType] = []
+                            viewData[postType].append( (coord, result) )
+                        else:
+                            Gmsh.send("  No data type for "+repr(result[0]), 
+                                    Gmsh.ERROR)
+                self.saveview(file, viewName, viewData)
+
+        if len(self.elementData):
+            Gmsh.send('Saving elemental results to %s'%file.name)
+            for (viewName, data) in self.elementData.items():
+                viewData = {}
+                for (eid, edata) in data.items():
+                    try:
+                        elem = self.elements[eid]
+                    except KeyError:
+                        Gmsh.send('  Mesh is missing element %d'%eid, 
+                                Gmsh.ERROR)
+                    else:
+                        coord = []
+                        for nid in elem[2]:
+                            # Gather node coordinates and results for this
+                            # element.
+                            try:
+                                coord.append(self.nodes[nid])
+                            except KeyError:
+                                Gmsh.send('  Mesh is missing node %d'%nid, 
+                                        Gmsh.ERROR)
+                        if len(elem[2]) == len(coord) and \
+                                self.elemTypes.has_key(elem[0]):
+                            # There was data available at every node for this
+                            # element and this element has a corresponding
+                            # post-processing object.
+                            result = [edata]*len(coord)
+                            if self.dataTypes.has_key(len(result[0][0])):
+                                postType = (self.dataTypes[len(result[0][0])]
+                                        + self.elemTypes[elem[0]])
+                                if not viewData.has_key(postType):
+                                    viewData[postType] = []
+                                viewData[postType].append( (coord, result) )
+                            else:
+                                Gmsh.send("  No data type for "+repr(result[0]),
+                                        Gmsh.ERROR)
+                self.saveview(file, viewName, viewData)
+
+###############################################################################
+# Main program begins here
+###############################################################################
+cmdline = Gmsh.getopt(sys.argv[1:])
+if cmdline.has_key('--socket'):
+    connection = Gmsh.Client(cmdline['--socket'])
+
+if cmdline.has_key('--help') or cmdline.has_key('-h'):
+    print __doc__
+elif cmdline.has_key('--options'):
+    Gmsh.send('--noaverage', Gmsh.OPTION)
+    Gmsh.send('--average', Gmsh.OPTION)
+else:
+    if not cmdline.has_key('--mesh'):
+        Gmsh.send("No mesh specified.", Gmsh.ERROR)
+        sys.exit(1)
+    if not cmdline.has_key('--results'):
+        Gmsh.send("No results specified.", Gmsh.ERROR)
+        sys.exit(1)
+
+    try:
+        mshfile = open(cmdline['--mesh'])
+        csvfile = open(cmdline['--results'])
+    except:
+        Gmsh.send(str(sys.exc_info()[1]), Gmsh.ERROR)
+    else:
+        pmesh = PostMesh()
+        pmesh.read(mshfile)
+        mshfile.close()
+        pmesh.csvparse(csvfile)
+        csvfile.close()
+        if cmdline.has_key('--average'):
+            Gmsh.send('Averaging data to one time step.')
+            for result in [ pmesh.nodalData, pmesh.elementData ]:
+                for view in result.keys():
+                    for (id, data) in result[view].items():
+                        nts = len(data)
+                        averaged = []
+                        for col in range(min(map(len, data))):
+                            sum = 0.0
+                            for d in data:
+                                sum += d[col]
+                            averaged.append(sum/nts)
+                        result[view][id] = [averaged]
+        try:
+            posfile = open(os.path.splitext(csvfile.name)[0]+'.pos', 'w')
+        except:
+            Gmsh.send(str(sys.exc_info()[1]), Gmsh.ERROR)
+        else:
+            pmesh.makeviews(posfile)
+            posfile.close()
+            Gmsh.send(posfile.name, Gmsh.VIEW)
diff --git a/utils/solvers/python/testcsv.csv b/utils/solvers/python/testcsv.csv
new file mode 100644
index 0000000000..f6289106a3
--- /dev/null
+++ b/utils/solvers/python/testcsv.csv
@@ -0,0 +1,200 @@
+1
+
+  ABAQUS VERSION 6.4-4                                     DATE 18-Jan-2005   TIME 17:42:16        PAGE     1
+
+
+
+
+
+
+    AAAAAA     BBBBBBBBB      AAAAAA      QQQQQQQQ    U        U    SSSSSSSS
+   A      A    B        B    A      A    Q        Q   U        U   S
+  A        A   B        B   A        A   Q        Q   U        U   S
+  A        A   B        B   A        A   Q        Q   U        U   S
+  AAAAAAAAAA   BBBBBBBBB    AAAAAAAAAA   Q        Q   U        U    SSSSSSSS
+  A        A   B        B   A        A   Q    Q   Q   U        U            S
+  A        A   B        B   A        A   Q     Q  Q   U        U            S
+  A        A   B        B   A        A   Q      Q Q   U        U            S
+  A        A   BBBBBBBBB    A        A    QQQQQQQQ     UUUUUUUU     SSSSSSSS
+
+
+
+
+                      This program has been developed by
+
+                                  ABAQUS, Inc.
+                                1080 Main Street
+                             Pawtucket, R.I. 02860
+
+
+
+
+
+
+                            P R O B L E M   S I Z E
+
+
+          NUMBER OF ELEMENTS IS                                   218
+          NUMBER OF NODES IS                                      131
+          NUMBER OF NODES DEFINED BY THE USER                     131
+          TOTAL NUMBER OF VARIABLES IN THE MODEL                  262
+          (DEGREES OF FREEDOM PLUS ANY LAGRANGE MULTIPLIER VARIABLES)
+
+
+
+                              END OF USER INPUT PROCESSING
+
+
+
+                        S T E P       1     S T A T I C   A N A L Y S I S
+
+
+
+                                INCREMENT     1 SUMMARY
+
+
+ TIME INCREMENT COMPLETED   1.00    ,  FRACTION OF STEP COMPLETED   1.00
+ STEP TIME COMPLETED        1.00    ,  TOTAL TIME COMPLETED         1.00
+
+
+
+                                                  E L E M E N T   O U T P U T
+
+
+
+
+
+   THE FOLLOWING TABLE IS PRINTED FOR ALL ELEMENTS WITH TYPE CPE3 AVERAGED AT THE NODES
+
+      node, temperature,               displacement, stress
+         2,       69.86,       8.4194E-04   0.000 0, -31.56 13.43 0 13.43 -329.1 0 0 0 -251.5
+         3,       39.96,       3.0836E-03   0.000 0, -1.491 -3.133 0 -3.133 -44.68 0 0 0 -97.55
+         4,       11.16,       1.9388E-03   0.000 0, 11.99 -10.21 0 -10.21 -116.0 0 0 0 -64.08
+         5,       13.47,        0.000       0.000 0, 37.40 1.292 0 1.292 -73.75 0 0 0 -49.52
+         6,       67.60,        0.000     -6.6056E-04 0, -21.23 6.614 0 6.614 -8.562 0 0 0 -148.1
+         7,       69.83,       8.3356E-04 -6.7009E-05 0, -21.90 33.08 0 33.08 -337.4 0 0 0 -251.5
+         8,       69.76,       8.0950E-04 -1.4135E-04 0, -23.03 62.61 0 62.61 -345.2 0 0 0 -254.9
+         9,       69.62,       7.9671E-04 -2.0956E-04 0, -40.32 70.09 0 70.09 -285.4 0 0 0 -240.2
+        10,       69.48,       7.5652E-04 -2.7698E-04 0, -54.81 86.73 0 86.73 -249.9 0 0 0 -234.0
+        11,       69.28,       7.0955E-04 -3.3576E-04 0, -63.35 94.38 0 94.38 -210.6 0 0 0 -224.6
+        12,       69.07,       6.6124E-04 -3.9676E-04 0, -74.58 95.83 0 95.83 -172.0 0 0 0 -216.2
+        13,       68.82,       6.0588E-04 -4.4704E-04 0, -74.75 84.32 0 84.32 -129.5 0 0 0 -202.5
+        14,       68.59,       5.3983E-04 -4.9435E-04 0, -72.84 72.02 0 72.02 -97.01 0 0 0 -191.8
+        15,       68.35,       4.7004E-04 -5.3725E-04 0, -70.10 59.18 0 59.18 -70.98 0 0 0 -182.3
+        16,       68.14,       3.9512E-04 -5.7221E-04 0, -59.27 44.19 0 44.19 -43.37 0 0 0 -170.3
+        17,       67.96,       3.2004E-04 -6.0584E-04 0, -53.38 33.76 0 33.76 -26.85 0 0 0 -164.6
+        18,       67.80,       2.4153E-04 -6.2869E-04 0, -45.07 24.73 0 24.73 -17.33 0 0 0 -157.7
+        19,       67.67,       1.6298E-04 -6.4554E-04 0, -35.73 16.37 0 16.37 -11.90 0 0 0 -151.8
+        20,       67.61,       8.2122E-05 -6.5673E-04 0, -28.73 6.691 0 6.691 -8.362 0 0 0 -148.7
+        21,       66.81,       9.8446E-04   0.000 0, -29.35 6.504 0 6.504 -289.6 0 0 0 -235.8
+        22,       63.73,       1.1361E-03   0.000 0, -40.65 5.472 0 5.472 -257.8 0 0 0 -224.4
+        23,       60.65,       1.2821E-03   0.000 0, -49.06 1.671 0 1.671 -208.1 0 0 0 -204.7
+        24,       57.54,       1.4246E-03   0.000 0, -50.58 -0.6161 0 -0.6161 -173.6 0 0 0 -187.8
+        25,       54.50,       1.5756E-03   0.000 0, -47.33 -1.646 0 -1.646 -152.7 0 0 0 -174.7
+        26,       51.55,       1.7358E-03   0.000 0, -42.15 -3.541 0 -3.541 -133.9 0 0 0 -161.3
+        27,       48.72,       1.9085E-03   0.000 0, -34.37 -4.128 0 -4.128 -117.9 0 0 0 -148.1
+        28,       46.10,       2.0976E-03   0.000 0, -28.24 -4.892 0 -4.892 -105.2 0 0 0 -137.1
+        29,       43.78,       2.3081E-03   0.000 0, -19.19 -5.296 0 -5.296 -89.82 0 0 0 -123.8
+        30,       41.81,       2.5322E-03   0.000 0, -13.39 -3.509 0 -3.509 -76.96 0 0 0 -114.7
+        31,       40.45,       2.7922E-03   0.000 0, -5.308 -3.571 0 -3.571 -63.00 0 0 0 -105.7
+        32,       39.12,       3.0185E-03  2.2115E-04 0, -2.576 -5.276 0 -5.276 -47.55 0 0 0 -96.55
+        33,       36.19,       2.8256E-03  4.1759E-04 0, -2.044 -9.147 0 -9.147 -65.46 0 0 0 -96.16
+        34,       30.51,       2.5157E-03  4.8788E-04 0, -0.7721 -14.20 0 -14.20 -90.33 0 0 0 -92.70
+        35,       22.25,       2.1581E-03  3.8111E-04 0, 2.853 -11.24 0 -11.24 -114.0 0 0 0 -80.06
+        36,       11.69,       1.3632E-03   0.000 0, 20.52 -7.606 0 -7.606 -92.20 0 0 0 -56.02
+        37,       12.84,       7.0866E-04   0.000 0, 37.23 -2.644 0 -2.644 -79.34 0 0 0 -47.26
+        38,       26.51,        0.000      1.1136E-04 0, 18.80 2.425 0 2.425 -73.57 0 0 0 -71.25
+        39,       36.98,        0.000      5.4140E-05 0, -1.709 3.663 0 3.663 -69.27 0 0 0 -96.91
+        40,       45.62,        0.000     -8.1302E-05 0, -18.69 6.841 0 6.841 -61.46 0 0 0 -118.2
+        41,       52.82,        0.000     -2.4234E-04 0, -31.92 9.526 0 9.526 -41.54 0 0 0 -131.9
+        42,       58.77,        0.000     -4.0527E-04 0, -41.24 9.057 0 9.057 -26.89 0 0 0 -143.7
+        43,       63.66,        0.000     -5.4837E-04 0, -33.13 7.239 0 7.239 -10.12 0 0 0 -147.6
+        44,       39.11,       1.4706E-03  2.1356E-04 0, -2.215 -16.24 0 -16.24 -107.1 0 0 0 -115.4
+        45,       51.64,       1.3526E-03  9.5846E-05 0, -22.39 -6.105 0 -6.105 -141.9 0 0 0 -157.7
+        46,       47.75,       5.5026E-04 -1.9718E-05 0, -12.23 17.50 0 17.50 -88.57 0 0 0 -130.3
+        47,       60.44,       1.2091E-03 -7.5841E-06 0, -44.20 8.877 0 8.877 -194.6 0 0 0 -197.9
+        48,       58.57,       2.2758E-04 -3.4992E-04 0, -35.73 26.28 0 26.28 -39.02 0 0 0 -146.2
+        49,       53.82,       8.5472E-04 -1.6590E-05 0, -14.35 18.67 0 18.67 -126.4 0 0 0 -154.2
+        50,       59.09,       1.0037E-03 -4.4003E-05 0, -31.44 22.41 0 22.41 -168.6 0 0 0 -184.0
+        51,       42.40,       2.0545E-03  1.6521E-04 0, -13.94 -17.69 0 -17.69 -98.98 0 0 0 -122.4
+        52,       29.42,       7.8391E-04  1.7522E-04 0, 11.99 -3.246 0 -3.246 -86.77 0 0 0 -85.40
+        53,       53.34,       1.5467E-03  5.7672E-05 0, -40.47 -7.413 0 -7.413 -148.0 0 0 0 -168.6
+        54,       61.16,       7.3601E-04 -1.7843E-04 0, -36.58 46.11 0 46.11 -139.8 0 0 0 -182.0
+        55,       64.37,       1.0845E-03 -3.5633E-05 0, -44.93 17.37 0 17.37 -250.6 0 0 0 -223.5
+        56,       58.10,       4.9318E-04 -2.3073E-04 0, -28.35 39.79 0 39.79 -86.64 0 0 0 -156.9
+        57,       33.97,       2.1313E-03  2.8372E-04 0, -2.154 -17.92 0 -17.92 -90.18 0 0 0 -98.58
+        58,       43.42,       1.0689E-03  1.4500E-04 0, -3.284 -3.999 0 -3.999 -112.8 0 0 0 -126.0
+        59,       62.17,       1.1621E-04 -4.9096E-04 0, -38.48 14.31 0 14.31 -19.57 0 0 0 -148.0
+        60,       63.27,       9.8677E-04 -9.1671E-05 0, -41.88 39.07 0 39.07 -213.4 0 0 0 -209.8
+        61,       47.33,       1.8777E-03  9.3115E-05 0, -28.91 -12.50 0 -12.50 -117.6 0 0 0 -143.9
+        62,       24.09,       1.4647E-03  2.1595E-04 0, 9.910 -12.59 0 -12.59 -94.44 0 0 0 -74.41
+        63,       43.83,       1.6560E-03  1.7798E-04 0, -12.67 -17.58 0 -17.58 -113.9 0 0 0 -129.5
+        64,       39.96,       2.5284E-03  1.6466E-04 0, -7.909 -12.34 0 -12.34 -77.77 0 0 0 -109.8
+        65,       63.48,       8.1289E-04 -1.8230E-04 0, -43.51 54.68 0 54.68 -168.6 0 0 0 -197.0
+        66,       55.78,       1.2850E-03  4.3255E-05 0, -32.66 -1.098 0 -1.098 -159.4 0 0 0 -174.1
+        67,       48.37,       1.1958E-03  1.1577E-04 0, -10.63 -4.579 0 -4.579 -128.9 0 0 0 -143.2
+        68,       36.16,       4.7265E-04  1.0862E-04 0, 0.7402 4.679 0 4.679 -82.59 0 0 0 -100.9
+        69,       56.96,       1.4146E-03  2.3575E-05 0, -46.39 -1.231 0 -1.231 -171.6 0 0 0 -185.1
+        70,       61.98,       5.6338E-04 -2.8586E-04 0, -38.12 51.00 0 51.00 -104.0 0 0 0 -172.5
+        71,       65.16,       9.8242E-04 -9.3900E-05 0, -37.02 43.60 0 43.60 -237.8 0 0 0 -219.4
+        72,       53.17,       1.0946E-03  4.9133E-05 0, -17.30 6.233 0 6.233 -141.0 0 0 0 -158.6
+        73,       48.36,       2.4764E-04 -1.1023E-04 0, -21.28 13.88 0 13.88 -63.61 0 0 0 -126.9
+        74,       42.44,       2.3173E-03  1.0627E-04 0, -14.60 -11.03 0 -11.03 -89.29 0 0 0 -120.0
+        75,       35.01,       1.1293E-03  2.0386E-04 0, 4.220 -9.489 0 -9.489 -99.26 0 0 0 -102.5
+        76,       64.86,       6.2305E-04 -3.2075E-04 0, -54.70 67.14 0 67.14 -112.6 0 0 0 -187.0
+        77,       50.21,       1.7736E-03  5.1510E-05 0, -37.30 -7.163 0 -7.163 -127.9 0 0 0 -155.1
+        78,       47.98,       1.6505E-03  1.2818E-04 0, -23.30 -13.91 0 -13.91 -125.9 0 0 0 -146.0
+        79,       60.89,       1.2466E-03 -5.0573E-06 0, -48.24 6.321 0 6.321 -208.8 0 0 0 -205.2
+        80,       38.36,       1.8932E-03  2.2949E-04 0, -5.402 -20.85 0 -20.85 -99.62 0 0 0 -112.0
+        81,       48.10,       8.1422E-04  5.0337E-05 0, -7.133 11.99 0 11.99 -109.7 0 0 0 -135.8
+        82,       60.72,       3.3586E-04 -3.6942E-04 0, -38.51 35.77 0 35.77 -53.49 0 0 0 -154.7
+        83,       39.97,       7.4362E-04  1.2307E-04 0, 0.1859 3.982 0 3.982 -94.25 0 0 0 -112.7
+        84,       65.54,       8.4336E-04 -1.9118E-04 0, -43.71 68.36 0 68.36 -201.5 0 0 0 -211.5
+        85,       32.16,       1.6376E-03  2.5023E-04 0, 2.514 -18.72 0 -18.72 -96.50 0 0 0 -95.80
+        86,       57.42,       6.8273E-04 -1.3380E-04 0, -22.90 35.16 0 35.16 -119.5 0 0 0 -163.4
+        87,       22.02,       4.5206E-04  1.1849E-04 0, 27.57 -0.5780 0 -0.5780 -78.37 0 0 0 -61.70
+        88,       27.06,       1.9435E-03  3.0431E-04 0, 2.174 -15.48 0 -15.48 -98.32 0 0 0 -85.54
+        89,       57.29,       9.1126E-04 -4.6903E-05 0, -24.34 23.77 0 23.77 -147.5 0 0 0 -171.9
+        90,       20.35,       1.0270E-03  1.4077E-04 0, 23.95 -6.210 0 -6.210 -86.24 0 0 0 -62.78
+        91,       53.78,       3.7698E-04 -1.8593E-04 0, -25.62 27.49 0 27.49 -69.66 0 0 0 -142.6
+        92,       53.39,       1.6126E-03  3.0206E-05 0, -45.13 -3.757 0 -3.757 -146.9 0 0 0 -170.3
+        93,       65.62,       7.0106E-04 -2.9006E-04 0, -55.91 74.27 0 74.27 -144.5 0 0 0 -198.0
+        94,       38.27,       2.2964E-03  2.2631E-04 0, -6.964 -17.67 0 -17.67 -86.84 0 0 0 -108.7
+        95,       66.38,       8.8448E-04 -1.6366E-04 0, -42.42 66.73 0 66.73 -239.6 0 0 0 -224.3
+        96,       59.54,       1.1434E-03 -1.0713E-05 0, -37.34 14.42 0 14.42 -183.4 0 0 0 -191.1
+        97,       45.13,       2.1104E-03  7.5866E-05 0, -23.85 -10.18 0 -10.18 -103.1 0 0 0 -132.7
+        98,       63.31,       2.2765E-04 -4.8975E-04 0, -41.71 25.96 0 25.96 -22.51 0 0 0 -152.7
+        99,       52.78,       6.2969E-04 -7.5140E-05 0, -15.72 26.76 0 26.76 -103.1 0 0 0 -147.0
+       100,       43.88,       1.3641E-03  1.6792E-04 0, -7.276 -12.54 0 -12.54 -119.0 0 0 0 -130.8
+       101,       47.33,       1.4363E-03  1.4140E-04 0, -14.20 -12.38 0 -12.38 -127.2 0 0 0 -141.6
+       102,       56.84,       1.3404E-03  3.2032E-05 0, -40.35 -0.8910 0 -0.8910 -168.0 0 0 0 -181.3
+       103,       63.68,       4.2738E-04 -4.0621E-04 0, -49.22 48.06 0 48.06 -64.35 0 0 0 -168.2
+       104,       50.09,       1.6750E-03  8.8554E-05 0, -33.07 -11.61 0 -11.61 -131.7 0 0 0 -154.9
+       105,       18.82,       1.7143E-03  1.8591E-04 0, 8.110 -9.748 0 -9.748 -106.3 0 0 0 -69.59
+       106,       66.56,       9.9793E-04 -3.3011E-05 0, -31.92 15.61 0 15.61 -288.6 0 0 0 -235.6
+       107,       40.03,       2.3416E-04  3.0424E-05 0, -8.431 6.413 0 6.413 -72.11 0 0 0 -108.2
+       108,       66.84,       9.5633E-04 -8.8428E-05 0, -30.30 42.13 0 42.13 -290.6 0 0 0 -236.8
+       109,       55.88,       1.1496E-03  2.8041E-05 0, -27.72 7.216 0 7.216 -160.8 0 0 0 -174.2
+       110,       47.46,       1.9630E-03  4.6760E-05 0, -30.85 -6.555 0 -6.555 -112.4 0 0 0 -142.7
+       111,       27.87,       1.1867E-03  2.0507E-04 0, 10.06 -11.70 0 -11.70 -92.79 0 0 0 -83.81
+       112,       65.42,       5.3018E-04 -3.9857E-04 0, -58.41 62.36 0 62.36 -84.20 0 0 0 -180.3
+       113,       55.60,       1.3108E-04 -3.0201E-04 0, -35.26 16.36 0 16.36 -41.02 0 0 0 -139.8
+       114,       39.83,       2.8067E-03  1.2332E-04 0, -3.517 -5.677 0 -5.677 -57.45 0 0 0 -101.9
+       115,       52.72,       1.4654E-03  7.8496E-05 0, -32.42 -8.561 0 -8.561 -145.4 0 0 0 -163.9
+       116,       42.43,       4.4960E-04  3.6423E-05 0, -7.868 10.95 0 10.95 -79.02 0 0 0 -115.2
+       117,       66.50,       7.5078E-04 -2.7189E-04 0, -54.98 83.04 0 83.04 -176.9 0 0 0 -209.3
+       118,       41.24,       2.5562E-03  7.5637E-05 0, -10.34 -5.624 0 -5.624 -75.38 0 0 0 -112.5
+       119,       60.45,       8.7062E-04 -1.1044E-04 0, -35.49 34.88 0 34.88 -164.6 0 0 0 -187.2
+       120,       61.95,       9.4380E-04 -9.8688E-05 0, -38.04 36.30 0 36.30 -183.3 0 0 0 -196.4
+       121,       35.48,       2.4940E-03  3.2925E-04 0, -2.175 -13.00 0 -13.00 -77.42 0 0 0 -98.28
+       122,       49.70,       9.8927E-04  6.7429E-05 0, -10.44 5.383 0 5.383 -126.0 0 0 0 -144.8
+       123,       63.08,       1.1594E-03 -1.3116E-05 0, -43.33 7.414 0 7.414 -234.5 0 0 0 -216.0
+       124,       56.01,       1.4914E-03  1.3061E-05 0, -49.84 -1.514 0 -1.514 -164.5 0 0 0 -182.1
+       125,       30.47,       3.0653E-04  1.2008E-04 0, 8.389 2.497 0 2.497 -76.10 0 0 0 -86.24
+       126,       58.42,       1.3757E-03  8.2717E-06 0, -49.91 0.3047 0 0.3047 -182.9 0 0 0 -192.5
+       127,       64.90,       3.0955E-04 -5.0667E-04 0, -50.18 35.88 0 35.88 -32.63 0 0 0 -161.6
+       128,       62.35,       1.0849E-03 -4.8287E-05 0, -40.94 22.78 0 22.78 -211.7 0 0 0 -206.7
+       129,       40.75,       2.2941E-03  1.6746E-04 0, -10.97 -16.67 0 -16.67 -89.00 0 0 0 -115.6
+       130,       38.08,       2.7138E-03  2.5436E-04 0, -3.250 -10.01 0 -10.01 -64.39 0 0 0 -100.3
+       131,       45.32,       1.8808E-03  1.3680E-04 0, -21.81 -16.15 0 -16.15 -112.0 0 0 0 -135.3
+       132,       63.26,       1.1019E-03 -4.0239E-05 0, -42.03 20.67 0 20.67 -226.9 0 0 0 -213.6
diff --git a/utils/solvers/python/testcsv.geo b/utils/solvers/python/testcsv.geo
new file mode 100644
index 0000000000..35f8799edf
--- /dev/null
+++ b/utils/solvers/python/testcsv.geo
@@ -0,0 +1,18 @@
+Point(1) = {0, 0, 0, 0.1};
+Point(2) = {1, 0, 0, 0.1};
+Point(3) = {4, 0, 0, 0.5};
+Point(4) = {4, 4, 0, 1.0};
+Point(5) = {0, 4, 0, 1.0};
+Point(6) = {0, 1, 0, 0.1};
+Circle(1) = {2,1,6};
+Line(2) = {2,3};
+Line(3) = {3,4};
+Line(4) = {4,5};
+Line(5) = {5,6};
+Line Loop(6) = {1,-5,-4,-3,-2};
+Plane Surface(7) = {6};
+Physical Line(101) = {5};
+Physical Line(102) = {2};
+Physical Line(112) = {4};
+Physical Line(200) = {1};
+Physical Surface(11) = {-7};
diff --git a/utils/solvers/python/testcsv.msh b/utils/solvers/python/testcsv.msh
new file mode 100644
index 0000000000..36c59b8192
--- /dev/null
+++ b/utils/solvers/python/testcsv.msh
@@ -0,0 +1,395 @@
+$MeshFormat
+2 0 8
+$EndMeshFormat
+$Nodes
+131
+2 1 0 0
+3 4 0 0
+4 4 4 0
+5 0 4 0
+6 0 1 0
+7 0.9945218953682734 0.104528463267653 0
+8 0.9781476007338058 0.2079116908177585 0
+9 0.951056516295154 0.3090169943749462 0
+10 0.9135454576426018 0.4067366430757982 0
+11 0.8660254037844408 0.4999999999999963 0
+12 0.8090169943749513 0.5877852522924678 0
+13 0.7431448254774 0.6691306063588518 0
+14 0.6691306063588659 0.7431448254773874 0
+15 0.5877852522924825 0.8090169943749406 0
+16 0.5000000000000111 0.8660254037844323 0
+17 0.4067366430758131 0.9135454576425951 0
+18 0.3090169943749584 0.95105651629515 0
+19 0.2079116908177668 0.978147600733804 0
+20 0.1045284632676574 0.994521895368273 0
+21 1.107660966482431 0 0
+22 1.230764829752582 0 0
+23 1.371542876294749 0 0
+24 1.532522866946499 0 0
+25 1.71659942352474 0 0
+26 1.927090777472968 0 0
+27 2.167782956522458 0 0
+28 2.443096045924229 0 0
+29 2.757877025314089 0 0
+30 3.117761880505327 0 0
+31 3.529324854187504 0 0
+32 4 0.5949066135025001 0
+33 4 1.278145619573775 0
+34 4 2.063201578232027 0
+35 4 2.964633608956098 0
+36 2.666666666666685 4 0
+37 1.33333333333337 4 0
+38 0 3.065647789360017 0
+39 0 2.393288956030129 0
+40 0 1.909232044233197 0
+41 0 1.560915832167684 0
+42 0 1.310258795174613 0
+43 0 1.129841025580155 0
+44 2.072632706027311 1.69598688973258 0
+45 1.613773926086385 0.8500227436870333 0
+46 0.8294669788088875 1.658857826312972 0
+47 1.32513596375101 0.3476839123937975 0
+48 0.3521126881546655 1.277363555436711 0
+49 1.12466853437021 1.153418043518669 0
+50 1.192696518113869 0.7306415166144991 0
+51 2.576053729862485 0.9053498230115412 0
+52 1.340126667186485 2.734096405958066 0
+53 1.726422310283826 0.4059954321843577 0
+54 0.9353736948832166 0.8715848956617313 0
+55 1.18615207058655 0.1857246235325533 0
+56 0.7052561075612429 1.175916841150846 0
+57 3.128587449887757 1.766432616500146 0
+58 1.502973959682794 1.639173253302476 0
+59 0.1759133514351944 1.169780059600397 0
+60 1.126589503584839 0.4922655384184934 0
+61 2.196140328827049 0.5068889305674 0
+62 2.612345788958327 2.921450948015479 0
+63 2.112581290158194 1.167800481700336 0
+64 3.237383018383969 0.7234638462140814 0
+65 0.9840394726232626 0.6906803311775085 0
+66 1.468485632956789 0.6195916609164185 0
+67 1.543585212840636 1.22337304019121 0
+68 0.7847572529703151 2.373911411047601 0
+69 1.536612492066048 0.2546061344524544 0
+70 0.7563814323183446 0.9674850965584817 0
+71 1.106950139898796 0.3511105542101679 0
+72 1.35889190895776 0.9986524025805176 0
+73 0.3959273532525635 1.738325897497147 0
+74 2.844593724249942 0.5138633427199154 0
+75 1.754062226045712 2.193549370361175 0
+76 0.7938495145246145 0.8047643924259087 0
+77 2.001875040491023 0.2863548721871211 0
+78 1.970700830475661 0.7993756598722095 0
+79 1.34411212289718 0.1825137374421063 0
+80 2.591371751876443 1.47181123899766 0
+81 1.145266577772124 1.501068978824429 0
+82 0.4941440667927327 1.148854074736235 0
+83 1.149429186474111 2.031817360579769 0
+84 0.9939713247765112 0.5426636213837798 0
+85 2.53934709873342 2.170371417857803 0
+86 0.9170333339922072 1.089415598156251 0
+87 0.8299773866185869 3.344838685871387 0
+88 3.289379674794993 2.516276442461847 0
+89 1.137453345295398 0.9199637046208775 0
+90 1.882033197768151 3.350776213150626 0
+91 0.5747040540405435 1.429957302128625 0
+92 1.775313987913787 0.1942086133302341 0
+93 0.8643434939808741 0.7017184961964265 0
+94 3.072389280032639 1.182610643612223 0
+95 1.025398445390052 0.425064443790196 0
+96 1.291599018349766 0.5379400141021424 0
+97 2.500950996588131 0.3796311220360604 0
+98 0.329249276924329 1.100214750608649 0
+99 0.894324716202368 1.353915876710289 0
+100 1.813941250117164 1.40844809571916 0
+101 1.794878469096937 1.088460304995382 0
+102 1.486769023536358 0.4427525772291758 0
+103 0.5900512883039151 0.9886452832900361 0
+104 1.926700328468347 0.5373153173291814 0
+105 3.279545588397917 3.324720918759852 0
+106 1.111952245445099 0.09914654476876072 0
+107 0.387323186063824 2.191864376335631 0
+108 1.078521106254799 0.230024464668231 0
+109 1.35920433836455 0.7749771722215344 0
+110 2.265435202084209 0.2409669473795033 0
+111 2.013801144774503 2.711101094307226 0
+112 0.6907699614193001 0.8590816528292089 0
+113 0.2143922726422754 1.42492042583774 0
+114 3.598069662403972 0.4358901037284767 0
+115 1.680368656509361 0.6158390637855682 0
+116 0.7133557167561021 1.999543410730382 0
+117 0.9072102561528353 0.6052161494598445 0
+118 3.178430153760137 0.3236365929559723 0
+119 1.063899507509137 0.7888937937290703 0
+120 1.1075300813509 0.6309016457330627 0
+121 3.544094384876648 1.445283348829069 0
+122 1.313711830501423 1.292934084685645 0
+123 1.253184469019452 0.1023441938573933 0
+124 1.616253868583924 0.119775562455931 0
+125 0.5355241979412432 2.779799497471038 0
+126 1.478800932191749 0.1185154109768451 0
+127 0.4286494767521648 1.012418382992747 0
+128 1.208825921620229 0.4088813796481784 0
+129 2.923716641100324 0.8451929254086457 0
+130 3.629773810408995 0.9401286651846473 0
+131 2.278190977419342 0.7701736465013063 0
+132 1.209925918352208 0.2871708528743117 0
+$EndNodes
+$Elements
+255
+1 1 2 101 5 5 38
+2 1 2 101 5 38 39
+3 1 2 101 5 39 40
+4 1 2 101 5 40 41
+5 1 2 101 5 41 42
+6 1 2 101 5 42 43
+7 1 2 101 5 43 6
+8 1 2 102 2 2 21
+9 1 2 102 2 21 22
+10 1 2 102 2 22 23
+11 1 2 102 2 23 24
+12 1 2 102 2 24 25
+13 1 2 102 2 25 26
+14 1 2 102 2 26 27
+15 1 2 102 2 27 28
+16 1 2 102 2 28 29
+17 1 2 102 2 29 30
+18 1 2 102 2 30 31
+19 1 2 102 2 31 3
+20 1 2 112 4 4 36
+21 1 2 112 4 36 37
+22 1 2 112 4 37 5
+23 1 2 200 1 2 7
+24 1 2 200 1 7 8
+25 1 2 200 1 8 9
+26 1 2 200 1 9 10
+27 1 2 200 1 10 11
+28 1 2 200 1 11 12
+29 1 2 200 1 12 13
+30 1 2 200 1 13 14
+31 1 2 200 1 14 15
+32 1 2 200 1 15 16
+33 1 2 200 1 16 17
+34 1 2 200 1 17 18
+35 1 2 200 1 18 19
+36 1 2 200 1 19 20
+37 1 2 200 1 20 6
+38 2 2 11 7 75 58 44
+39 2 2 11 7 80 63 51
+40 2 2 11 7 59 43 20
+41 2 2 11 7 72 45 67
+42 2 2 11 7 101 67 45
+43 2 2 11 7 80 44 63
+44 2 2 11 7 59 20 19
+45 2 2 11 7 85 75 44
+46 2 2 11 7 131 97 51
+47 2 2 11 7 83 46 81
+48 2 2 11 7 83 81 58
+49 2 2 11 7 98 59 19
+50 2 2 11 7 83 58 75
+51 2 2 11 7 43 6 20
+52 2 2 11 7 100 44 58
+53 2 2 11 7 97 74 51
+54 2 2 11 7 79 69 47
+55 2 2 11 7 93 65 54
+56 2 2 11 7 89 86 54
+57 2 2 11 7 111 75 85
+58 2 2 11 7 95 9 71
+59 2 2 11 7 89 49 86
+60 2 2 11 7 113 91 73
+61 2 2 11 7 113 48 91
+62 2 2 11 7 108 71 9
+63 2 2 11 7 84 11 10
+64 2 2 11 7 102 47 69
+65 2 2 11 7 118 74 29
+66 2 2 11 7 108 7 106
+67 2 2 11 7 108 8 7
+68 2 2 11 7 91 82 56
+69 2 2 11 7 88 57 34
+70 2 2 11 7 118 29 30
+71 2 2 11 7 131 61 97
+72 2 2 11 7 91 48 82
+73 2 2 11 7 86 70 54
+74 2 2 11 7 95 84 10
+75 2 2 11 7 127 16 103
+76 2 2 11 7 127 17 16
+77 2 2 11 7 76 14 13
+78 2 2 11 7 121 34 57
+79 2 2 11 7 98 19 18
+80 2 2 11 7 93 54 76
+81 2 2 11 7 109 50 96
+82 2 2 11 7 113 42 59
+83 2 2 11 7 90 87 52
+84 2 2 11 7 99 49 81
+85 2 2 11 7 83 75 52
+86 2 2 11 7 76 54 70
+87 2 2 11 7 73 40 41
+88 2 2 11 7 115 78 45
+89 2 2 11 7 85 44 80
+90 2 2 11 7 59 42 43
+91 2 2 11 7 77 26 27
+92 2 2 11 7 119 54 65
+93 2 2 11 7 131 51 63
+94 2 2 11 7 112 103 15
+95 2 2 11 7 120 96 50
+96 2 2 11 7 83 52 68
+97 2 2 11 7 109 89 50
+98 2 2 11 7 90 37 87
+99 2 2 11 7 109 72 89
+100 2 2 11 7 115 104 78
+101 2 2 11 7 99 86 49
+102 2 2 11 7 123 106 22
+103 2 2 11 7 113 73 41
+104 2 2 11 7 94 80 51
+105 2 2 11 7 92 53 69
+106 2 2 11 7 109 96 66
+107 2 2 11 7 97 29 74
+108 2 2 11 7 90 62 36
+109 2 2 11 7 106 7 2
+110 2 2 11 7 93 76 13
+111 2 2 11 7 125 68 52
+112 2 2 11 7 106 2 21
+113 2 2 11 7 122 49 72
+114 2 2 11 7 103 16 15
+115 2 2 11 7 108 9 8
+116 2 2 11 7 95 10 9
+117 2 2 11 7 122 81 49
+118 2 2 11 7 106 21 22
+119 2 2 11 7 101 45 78
+120 2 2 11 7 105 36 62
+121 2 2 11 7 120 60 96
+122 2 2 11 7 113 59 48
+123 2 2 11 7 100 63 44
+124 2 2 11 7 112 14 76
+125 2 2 11 7 87 37 5
+126 2 2 11 7 85 80 57
+127 2 2 11 7 132 55 79
+128 2 2 11 7 115 102 53
+129 2 2 11 7 125 52 87
+130 2 2 11 7 88 85 57
+131 2 2 11 7 110 77 27
+132 2 2 11 7 92 26 77
+133 2 2 11 7 124 92 69
+134 2 2 11 7 89 72 49
+135 2 2 11 7 102 69 53
+136 2 2 11 7 125 39 107
+137 2 2 11 7 122 72 67
+138 2 2 11 7 100 58 67
+139 2 2 11 7 129 94 51
+140 2 2 11 7 109 66 45
+141 2 2 11 7 123 79 55
+142 2 2 11 7 99 91 56
+143 2 2 11 7 122 67 58
+144 2 2 11 7 115 66 102
+145 2 2 11 7 86 56 70
+146 2 2 11 7 111 85 62
+147 2 2 11 7 104 53 77
+148 2 2 11 7 116 46 83
+149 2 2 11 7 97 28 29
+150 2 2 11 7 87 5 38
+151 2 2 11 7 116 73 46
+152 2 2 11 7 125 107 68
+153 2 2 11 7 92 77 53
+154 2 2 11 7 91 46 73
+155 2 2 11 7 115 45 66
+156 2 2 11 7 107 40 73
+157 2 2 11 7 132 79 47
+158 2 2 11 7 99 56 86
+159 2 2 11 7 93 13 12
+160 2 2 11 7 109 45 72
+161 2 2 11 7 130 94 64
+162 2 2 11 7 103 70 56
+163 2 2 11 7 131 63 78
+164 2 2 11 7 127 98 18
+165 2 2 11 7 117 11 84
+166 2 2 11 7 130 121 94
+167 2 2 11 7 123 55 106
+168 2 2 11 7 92 25 26
+169 2 2 11 7 88 62 85
+170 2 2 11 7 95 71 60
+171 2 2 11 7 122 58 81
+172 2 2 11 7 112 70 103
+173 2 2 11 7 102 96 47
+174 2 2 11 7 114 3 32
+175 2 2 11 7 123 23 79
+176 2 2 11 7 101 78 63
+177 2 2 11 7 114 31 3
+178 2 2 11 7 128 60 71
+179 2 2 11 7 101 100 67
+180 2 2 11 7 125 38 39
+181 2 2 11 7 126 79 23
+182 2 2 11 7 129 51 74
+183 2 2 11 7 112 76 70
+184 2 2 11 7 121 33 34
+185 2 2 11 7 118 30 31
+186 2 2 11 7 103 56 82
+187 2 2 11 7 88 34 35
+188 2 2 11 7 105 35 4
+189 2 2 11 7 126 69 79
+190 2 2 11 7 127 18 17
+191 2 2 11 7 105 62 88
+192 2 2 11 7 98 48 59
+193 2 2 11 7 104 61 78
+194 2 2 11 7 118 31 114
+195 2 2 11 7 115 53 104
+196 2 2 11 7 94 57 80
+197 2 2 11 7 120 119 65
+198 2 2 11 7 111 90 52
+199 2 2 11 7 108 106 55
+200 2 2 11 7 101 63 100
+201 2 2 11 7 117 12 11
+202 2 2 11 7 131 78 61
+203 2 2 11 7 123 22 23
+204 2 2 11 7 111 52 75
+205 2 2 11 7 120 50 119
+206 2 2 11 7 107 39 40
+207 2 2 11 7 104 77 61
+208 2 2 11 7 110 27 28
+209 2 2 11 7 102 66 96
+210 2 2 11 7 99 46 91
+211 2 2 11 7 113 41 42
+212 2 2 11 7 110 28 97
+213 2 2 11 7 112 15 14
+214 2 2 11 7 105 88 35
+215 2 2 11 7 95 60 84
+216 2 2 11 7 117 93 12
+217 2 2 11 7 99 81 46
+218 2 2 11 7 116 107 73
+219 2 2 11 7 110 61 77
+220 2 2 11 7 111 62 90
+221 2 2 11 7 119 89 54
+222 2 2 11 7 132 71 108
+223 2 2 11 7 132 108 55
+224 2 2 11 7 118 64 74
+225 2 2 11 7 98 82 48
+226 2 2 11 7 124 25 92
+227 2 2 11 7 120 65 84
+228 2 2 11 7 129 74 64
+229 2 2 11 7 126 23 24
+230 2 2 11 7 128 96 60
+231 2 2 11 7 120 84 60
+232 2 2 11 7 119 50 89
+233 2 2 11 7 125 87 38
+234 2 2 11 7 128 47 96
+235 2 2 11 7 110 97 61
+236 2 2 11 7 117 84 65
+237 2 2 11 7 116 83 68
+238 2 2 11 7 121 57 94
+239 2 2 11 7 124 24 25
+240 2 2 11 7 130 64 114
+241 2 2 11 7 127 103 82
+242 2 2 11 7 129 64 94
+243 2 2 11 7 117 65 93
+244 2 2 11 7 130 114 32
+245 2 2 11 7 132 128 71
+246 2 2 11 7 118 114 64
+247 2 2 11 7 126 24 124
+248 2 2 11 7 130 33 121
+249 2 2 11 7 116 68 107
+250 2 2 11 7 126 124 69
+251 2 2 11 7 132 47 128
+252 2 2 11 7 127 82 98
+253 2 2 11 7 90 36 37
+254 2 2 11 7 105 4 36
+255 2 2 11 7 130 32 33
+$EndElements
-- 
GitLab