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 Jul 9, 2021
1 parent 84ec44a commit 68070cc
Show file tree
Hide file tree
Showing 4 changed files with 249 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/Mod/Fem/CMakeLists.txt
Expand Up @@ -214,6 +214,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
2 changes: 1 addition & 1 deletion src/Mod/Fem/femsolver/oofem/solver.py
Expand Up @@ -32,7 +32,7 @@

import FreeCAD

# from . import tasks
from . import tasks
from .. import run
from .. import solverbase
from femtools import femutils
Expand Down
126 changes: 126 additions & 0 deletions src/Mod/Fem/femsolver/oofem/tasks.py
@@ -0,0 +1,126 @@
# ***************************************************************************
# * Copyright (c) 2019 Bernd Hahnebach <bernd@bimstatik.org> *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
# * 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"

## \addtogroup FEM
# @{

import os
import os.path
import subprocess

import FreeCAD

from . import writer
from .. import run
from .. import settings
from femtools import membertools


_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")
w = writer.FemInputWriterOOFEM(
self.analysis,
self.solver,
None, # membertools.get_mesh_to_solve(self.analysis)[0],
membertools.AnalysisMember(self.analysis),
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"
resobj.ViewObject.Document.activeView().viewIsometric()
resobj.ViewObject.Document.activeView().fitAll()
self.solver.Document.recompute()
self.analysis.addObject(resobj)
# TODO add a wrap factor
else:
raise Exception(
"FEM: No results found at {}!".format(res_file))

## @}
120 changes: 120 additions & 0 deletions src/Mod/Fem/femsolver/oofem/writer.py
@@ -0,0 +1,120 @@
# ***************************************************************************
# * Copyright (c) 2019 Bernd Hahnebach <bernd@bimstatik.org> *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
# * 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 time

import FreeCAD

from .. import writerbase


class FemInputWriterOOFEM(writerbase.FemInputWriter):
def __init__(
self,
analysis_obj,
solver_obj,
mesh_obj,
member,
dir_name=None
):
writerbase.FemInputWriter.__init__(
self,
analysis_obj,
solver_obj,
mesh_obj,
member,
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(
"FemInputWriterOOFEM --> self.dir_name --> {}\n"
.format(self.dir_name)
)
FreeCAD.Console.PrintLog(
"FemInputWriterOOFEM --> self.main_file_name --> {}\n"
.format(self.main_file_name)
)
FreeCAD.Console.PrintMessage(
"FemInputWriterOOFEM --> self.file_name --> {}\n"
.format(self.file_name)
)

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 68070cc

Please sign in to comment.