Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Object Oriented Fortran/read a file and set Variables

Status
Not open for further replies.

archimedes80

Technical User
May 3, 2010
11
DE
Hello All,

is there a possibility to read the following in Object Oriented manner?

SOLVER:
Iterative Method (GAUSS-SEIDEL/JACOBI) : JACOBI
Iterations : 300
Dynamic Breakcriteria (yes/no) : yes
Absolute Breakcriteria : 10e-7
END SOLVER

thank you in advance
 

It is rather easy to read these data but I would like to learn the meaning of "reading in an object oriented manner"

As Richard Maine, in comp.lang.fortran, noticed recently :

"Object oriented" is largely a buzz word that can mean different things to different people. (And quite a few people obviously have not the faintest idea of what it might mean at all, except that someone else told them it was good, whatever it was)."

François Jacq
 
You are right and i'm sorry for this misunderstanding.
I know it is easy to read, that's no my problem.
Let me reexamine the question. Is there a technique in fortran to read that file, or eventually many other similar files with the use of one Derived Type in one Module?

I hope that time the question does make sense. I'm sorry for my English and thank you in advance.
 

Do not apologize about English : I am, probably like you, a non native English person.

About your question, which looks like homework, I will only help you if you propose, at least, a beginning of solution
which does not run as expected.

So please, publish a first attempt of the module which defines the derived type "solver_type" and implements a reading subroutine initializing a variable of that type.


François Jacq
 
Yes! That's true mikrom and I try to rewrite this in an other way.

It's not a homework FJacq but i'll try to do what you've suggested me.

I'm one of those people who believes that the new Fortran Standard is light years in advance than other Languages (see Co Arrays), so I do training myself mostly at home related to Fortran. But as Goethe said "The one who believes that he can learn himself, he has a bad teacher" so i found the forum for further help. Of course I know people they are very good in Fortran but
I learned here a lot also from other posts (and thank you mikron, he was the first who helped me here) but i do not want to stop here. I would like to be able in the future to help other people related to fortran. That's also the main reason i want to rewrite what mikron suggested me. I think it's a good way to learn programming. Trying to rewrite the same thing in other ways.

Please be patient while I'm doing my "homework" FJacq gave me and the next time I promise I'll choose my words better to define my problem from the beginning.
 
Ok, but I don't understand what you mean with OO?
As far I know Fortran is not OO language from its nature.
Though I found something about OO concepts in Fortran, I never practiced OO in Fortran myself and I thing it would be more complicated than the simple approach I showed you in previous thread.

And what you mean with derived type?
IMHO, for the task you only need as data type the text line, which is for example character(80). Hovever you can define your own data type for it.

To make the things universal, I would suggest you to wrap the functionality from previous thread in a module.
This should not be very difficult.
 
Hello and I'm sorry for the late answer. I was thinking again about this problem and yesterday i wrote the following, which could be coupled with the subroutine mikrom gave to me. It works with gfortran, ftn but not with g95:

Code:
MODULE module_filehand

  IMPLICIT NONE

  TYPE :: filehand_t
    PRIVATE
    CHARACTER(len=64) :: filename
    INTEGER           :: fnunit
  CONTAINS
    PROCEDURE :: set_filehand   => set_filehand_sub
    PROCEDURE :: set_filename   => set_filename_sub
    PROCEDURE :: set_unit       => set_unit_sub
    PROCEDURE :: get_filename   => get_filename_fun
    PROCEDURE :: get_unit       => get_unit_fun
    PROCEDURE :: open_filehand  => open_filehand_sub
    PROCEDURE :: close_filehand => close_filehand_sub
  END TYPE filehand_t

CONTAINS
!******************************************************************************
!==============================================================================
SUBROUTINE set_filehand_sub(this, fn, un)
! Initialize filehand data
  CLASS(filehand_t) :: this
  CHARACTER(len=*)  :: fn
  INTEGER           :: un

  this%filename = fn
  this%fnunit   = un
END SUBROUTINE set_filehand_sub
!==============================================================================
SUBROUTINE set_filename_sub(this, fn)
! Initialize filename
  CLASS(filehand_t) :: this
  CHARACTER(len=*)  :: fn

  this%filename = fn
END SUBROUTINE set_filename_sub
!==============================================================================
SUBROUTINE set_unit_sub(this, un)
! Initialize unit
  CLASS(filehand_t) :: this
  INTEGER           :: un

  this%fnunit = un
END SUBROUTINE set_unit_sub
!==============================================================================
CHARACTER(len=64) FUNCTION get_filename_fun(this)
! Function to get filename
  CLASS(filehand_t) :: this

  get_filename_fun = this%filename
END FUNCTION get_filename_fun
!==============================================================================
INTEGER FUNCTION get_unit_fun(this)
! Function to get unit
  CLASS(filehand_t) :: this

  get_unit_fun = this%fnunit
END FUNCTION get_unit_fun
!==============================================================================
SUBROUTINE open_filehand_sub(this, fn, un)
! Open a file
  CLASS(filehand_t) :: this
  CHARACTER(len=*)  :: fn
  INTEGER           :: un, ios

  un = this%get_unit(); fn = this%get_filename()
  OPEN(unit=un, file=fn, action='read', status='old', iostat=ios)
  IF (ios == 0) print *, 'File opened succesfully'
END SUBROUTINE open_filehand_sub
!==============================================================================
SUBROUTINE close_filehand_sub(this, un)
! Close a file
  CLASS(filehand_t) :: this
  INTEGER           :: un, ios

  un = this%get_unit()
  close(unit=un, iostat=ios)
  IF (ios == 0) print *, 'File closed succesfully'
END SUBROUTINE close_filehand_sub
!==============================================================================
!******************************************************************************
END MODULE module_filehand



program filehand
use module_filehand

implicit none


  TYPE(filehand_t) :: meshfile!, filename2

  call meshfile%set_filehand('Naca0009.geo', 10)
  call meshfile%open_filehand(meshfile%get_filename(), meshfile%get_unit())
  call meshfile%close_filehand(meshfile%get_unit())

end program filehand



 
The code will only work on compilers which support the 2003 standard (contains in type definitions, class keyword), which it why it doesn't work in g95.
 
Alternatively, you could code it the way we used to do it in C, before C++ and Objective C took off. That will work on F90 compilers. The problem with this technique is that there is no equivalent of the v-table (which you have done with the procedure pointers) and, as such, concepts like inheritence are non-existent.

With the older compilers, the v-tables can be implemented using Cray Pointers but they are vendor specific as not all compilers accept Cray Pointers.
Code:
MODULE FilehandMod

  IMPLICIT NONE

  TYPE :: filehand_t
    PRIVATE
    CHARACTER(len=64) :: filename
    INTEGER           :: fnunit
  END TYPE filehand_t

CONTAINS
SUBROUTINE FilehandSet(this, fn, un)
! Initialize filehand data
  type(filehand_t) :: this
  CHARACTER(len=*)  :: fn
  INTEGER           :: un

  this%filename = fn
  this%fnunit   = un
END SUBROUTINE FilehandSet
!==============================================================================
CHARACTER(len=64) FUNCTION FilehandFilenameGet(this)
! Function to get filename
  type(filehand_t) :: this

  FilehandFilenameGet = this%filename
END FUNCTION FilehandFilenameGet
!==============================================================================
INTEGER FUNCTION FilehandUnitGet(this)
! Function to get unit
  type(filehand_t) :: this

  FilehandUnitGet = this%fnunit
END FUNCTION FilehandUnitGet
!==============================================================================
SUBROUTINE FilehandOpen(this)
! Open a file
  type(filehand_t) :: this
  INTEGER           :: un, ios

  un = FilehandUnitGet(this)
  OPEN(unit=un, file=FilehandFilenameGet(this), action='read', status='old', iostat=ios)
  IF (ios == 0) print *, 'File opened succesfully'
END SUBROUTINE FilehandOpen
!==============================================================================
SUBROUTINE FilehandClose(this)
! Close a file
  type(filehand_t) :: this
  INTEGER           :: un, ios

  un = FilehandUnitGet(this)
  close(unit=un, iostat=ios)
  IF (ios == 0) print *, 'File closed succesfully'
END SUBROUTINE FilehandClose
!==============================================================================
END MODULE FilehandMod

program filehand
   use FilehandMod

   implicit none

   type(filehand_t) :: meshfile

   call FilehandSet(meshfile, 'Naca0009.geo', 10)
   call FilehandOpen(meshfile)
   call FilehandClose(meshfile)

end program filehand
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top