Skip to content

Commit

Permalink
FEM: oofem tasks and writer, add modules:
Browse files Browse the repository at this point in the history
- the solver runs :-) with a dummy input file
- a string in writer is used as dummy input file
  • Loading branch information
berndhahnebach committed Sep 11, 2019
1 parent 080f323 commit a3cb4c4
Show file tree
Hide file tree
Showing 3 changed files with 327 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Mod/Fem/CMakeLists.txt
Expand Up @@ -124,6 +124,8 @@ SET(FemSolverFenics_SRCS
SET(FemSolverOOFEM_SRCS
femsolver/oofem/__init__.py
femsolver/oofem/solver.py
femsolver/oofem/tasks.py
femsolver/oofem/writer.py
)

SET(FemSolverZ88_SRCS
Expand Down
181 changes: 181 additions & 0 deletions src/Mod/Fem/femsolver/oofem/tasks.py
@@ -0,0 +1,181 @@
# ***************************************************************************
# * Copyright (c) 2019 Bernd Hahnebach <bernd@bimstatik.org> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************


__title__ = "OOFEM Tasks"
__author__ = "Bernd Hahnebach"
__url__ = "http://www.freecadweb.org"


import os
import subprocess
import os.path

import FreeCAD
import femtools.femutils as femutils

from .. import run
from .. import settings
from . import writer


_inputFileName = None


class Check(run.Check):

def run(self):
self.pushStatus("Checking analysis...\n")
# self.checkMesh()
# self.checkMaterial()


class Prepare(run.Prepare):

def run(self):
global _inputFileName
self.pushStatus("Preparing input files...\n")
c = _Container(self.analysis)
w = writer.FemInputWriterOOFEM(
self.analysis,
self.solver,
c.mesh,
c.materials_linear,
c.materials_nonlinear,
c.constraints_fixed,
c.constraints_displacement,
c.constraints_contact,
c.constraints_planerotation,
c.constraints_transform,
c.constraints_selfweight,
c.constraints_force,
c.constraints_pressure,
c.constraints_temperature,
c.constraints_heatflux,
c.constraints_initialtemperature,
c.beam_sections,
c.beam_rotations,
c.shell_thicknesses,
c.fluid_sections,
self.directory
)
path = w.write_OOFEM_input_file()
# report to user if task succeeded
if path is not None:
self.pushStatus("Write completed!")
else:
self.pushStatus("Writing OOFEM input files failed!")
_inputFileName = os.path.splitext(os.path.basename(path))[0]


class Solve(run.Solve):

def run(self):
if not _inputFileName:
# TODO do not run solver, do not try to read results in a smarter way than an Exception
raise Exception('Error on writing OOFEM input file.\n')
infile = _inputFileName + '.in'
FreeCAD.Console.PrintError('OOFEM-info: infile: {} \n\n'.format(infile))

self.pushStatus("Executing solver...\n")
binary = settings.get_binary("oofem")
# if something goes wrong the binary path could be set for debugging
# binary = '/usr/bin/oofem'
self._process = subprocess.Popen(
[binary, "-f", infile],
cwd=self.directory,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
self.signalAbort.add(self._process.terminate)
self._process.communicate()
self.signalAbort.remove(self._process.terminate)
# for chatching the output see CalculiX or Elmer solver task module


class Results(run.Results):

def run(self):
if not _inputFileName:
# TODO do not run solver, do not try to read results in a smarter way than an Exception
raise Exception('Error on writing OOFEM input file.\n')
self.load_results_oofem()

def load_results_oofem(self):
res_file = os.path.join(self.directory, "2DPlaneStress.out.m0.1.vtu")
FreeCAD.Console.PrintError('OOFEM-info: refile: ' + res_file + ' \n')
if os.path.isfile(res_file):
result_name_prefix = 'OOFEM_' + "2DPlaneStress"
from feminout.importVTKResults import importVtkVtkResult as importVTU
resobj = importVTU(res_file, result_name_prefix)
if FreeCAD.GuiUp:
resobj.ViewObject.DisplayMode = 'Surface with Edges'
resobj.ViewObject.Field = 'DisplacementVector'
import FreeCADGui
FreeCADGui.SendMsgToActiveView("ViewFit")
FreeCADGui.ActiveDocument.activeView().viewIsometric()
self.solver.Document.recompute()
self.analysis.addObject(resobj)
# TODO add a wrap factor
else:
raise Exception(
'FEM: No results found at {}!'.format(res_file))


class _Container(object):

def __init__(self, analysis):
self.analysis = analysis

# ****************************************************************************************
# ATM no member are collected, to test the solver:
# start FreeCAD, make a new document
# add an analysis, add a oofem solver and run the solver
# the dummy inputfile which is a string at end of writer module is written to
# the file 2DPlaneStress.in
# results will be loaded
# ****************************************************************************************

# get mesh
self.mesh = None

# get member, empty lists are not supported by oofem
self.materials_linear = []
self.materials_nonlinear = []

self.beam_sections = []
self.beam_rotations = []
self.fluid_sections = []
self.shell_thicknesses = []

self.constraints_contact = []
self.constraints_displacement = []
self.constraints_fixed = []
self.constraints_force = []
self.constraints_heatflux = []
self.constraints_initialtemperature = []
self.constraints_pressure = []
self.constraints_planerotation = []
self.constraints_selfweight = []
self.constraints_temperature = []
self.constraints_transform = []

def get_several_member(self, t):
return femutils.get_several_member(self.analysis, t)
144 changes: 144 additions & 0 deletions src/Mod/Fem/femsolver/oofem/writer.py
@@ -0,0 +1,144 @@
# ***************************************************************************
# * Copyright (c) 2019 Bernd Hahnebach <bernd@bimstatik.org> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************

__title__ = "OOFEM Writer"
__author__ = "Bernd Hahnebach"
__url__ = "http://www.freecadweb.org"

## \addtogroup FEM
# @{

import FreeCAD
import time
from .. import writerbase as FemInputWriter


class FemInputWriterOOFEM(FemInputWriter.FemInputWriter):
def __init__(
self,
analysis_obj,
solver_obj,
mesh_obj,
matlin_obj,
matnonlin_obj,
fixed_obj,
displacement_obj,
contact_obj,
planerotation_obj,
transform_obj,
selfweight_obj,
force_obj,
pressure_obj,
temperature_obj,
heatflux_obj, initialtemperature_obj,
beamsection_obj,
beamrotation_obj,
shellthickness_obj,
fluidsection_obj,
dir_name=None
):
FemInputWriter.FemInputWriter.__init__(
self,
analysis_obj,
solver_obj,
mesh_obj,
matlin_obj,
matnonlin_obj,
fixed_obj,
displacement_obj,
contact_obj,
planerotation_obj,
transform_obj,
selfweight_obj,
force_obj,
pressure_obj,
temperature_obj,
heatflux_obj,
initialtemperature_obj,
beamsection_obj,
beamrotation_obj,
shellthickness_obj,
fluidsection_obj,
dir_name
)
# working dir and input file
from os.path import join
# self.main_file_name = self.mesh_object.Name + '.in'
self.main_file_name = '2DPlaneStress.in'
self.file_name = join(self.dir_name, self.main_file_name)
FreeCAD.Console.PrintLog(
'FemInputWriterCcx --> self.dir_name --> ' + self.dir_name + '\n'
)
FreeCAD.Console.PrintLog(
'FemInputWriterCcx --> self.main_file_name --> ' + self.main_file_name + '\n'
)
FreeCAD.Console.PrintMessage(
'FemInputWriterCcx --> self.file_name --> ' + self.file_name + '\n'
)

def write_OOFEM_input_file(self):

timestart = time.clock()

inpfile = open(self.file_name, 'w')

inpfile.write(example_input_file)
inpfile.close()
writing_time_string = (
"Writing time input file: {} seconds"
.format(round((time.clock() - timestart), 2))
)
FreeCAD.Console.PrintMessage(writing_time_string + ' \n\n')
return self.file_name


example_input_file = '''2DPlaneStress.out
Patch test of PlaneStress2d elements -> pure compression
LinearStatic nsteps 1 nmodules 1
vtkxml tstep_all domain_all primvars 1 1 vars 5 1 2 4 5 27 stype 2
domain 2dPlaneStress
OutputManager tstep_all dofman_all element_all
ndofman 8 nelem 5 ncrosssect 1 nmat 1 nbc 3 nic 0 nltf 1 nset 3
node 1 coords 3 0.0 0.0 0.0
node 2 coords 3 0.0 4.0 0.0
node 3 coords 3 2.0 2.0 0.0
node 4 coords 3 3.0 1.0 0.0
node 5 coords 3 8.0 0.8 0.0
node 6 coords 3 7.0 3.0 0.0
node 7 coords 3 9.0 0.0 0.0
node 8 coords 3 9.0 4.0 0.0
PlaneStress2d 1 nodes 4 1 4 3 2 NIP 1
PlaneStress2d 2 nodes 4 1 7 5 4 NIP 1
PlaneStress2d 3 nodes 4 4 5 6 3 NIP 1
PlaneStress2d 4 nodes 4 3 6 8 2 NIP 1
PlaneStress2d 5 nodes 4 5 7 8 6 NIP 1
Set 1 elementranges {(1 5)}
Set 2 nodes 2 1 2
Set 3 nodes 2 7 8
SimpleCS 1 thick 1.0 width 1.0 material 1 set 1
IsoLE 1 d 0. E 15.0 n 0.25 talpha 1.0
BoundaryCondition 1 loadTimeFunction 1 dofs 2 1 2 values 1 0.0 set 2
BoundaryCondition 2 loadTimeFunction 1 dofs 1 2 values 1 0.0 set 3
NodalLoad 3 loadTimeFunction 1 dofs 2 1 2 components 2 2.5 0.0 set 3
ConstantFunction 1 f(t) 1.0
'''

## @}

0 comments on commit a3cb4c4

Please sign in to comment.