Personal tools
You are here: Home / cm / Wiki / Fortran Style Guide
Navigation
Log in


Forgot your password?
 

Fortran Style Guide

<ul><li><a name="tex2html3" href="#SECTION00020000000000000000">Introduction</a> </li><li><a name="tex2html4" href="#SECTION00030000000000000000">Subroutines and Functions</a> </li><li><a name="tex2html5" href="#SECTION00040000000000000000">Commenting Styles</a> </li><li><a name="tex2html6" href="#SECTION00050000000000000000">DO loop format</a> </li><li><a name="tex2html7" href="#SECTION00060000000000000000">IF statement format</a> </li><li><a name="tex2html8" href="#SECTION00070000000000000000">General</a> </li><li><a name="tex2html9" href="#SECTION00080000000000000000">CM CMGUI Link Code</a> </li></ul> <!--End of Table of Contents-->

<p>

</p><h1><a name="SECTION00020000000000000000"> Introduction</a> </h1>

<p> The purpose of this document is to outline the programming style all CMISS programmers should adopt when adding to/extending or otherwise altering Fortran code in CMISS.

</p><p>

</p><h1><a name="SECTION00030000000000000000"> Subroutines and Functions</a> </h1>

<p> The following is a sample subroutine (blank lines are to be included as well)

</p><p> </p><pre> SUBROUTINE SAMPLE(integer variable names in alphabetic order,<br> real variable names in alphabetic order,<br> complex variable names in alphabetic order,<br> character variable names in alphabetic order,<br> logical variable names in alphabetic order,<br> ERROR,*)<br> <br>C#### Subroutine: SAMPLE<br>C### Description:<br>C### Provides an example for programmers to copy when creating new<br>C### subroutines. A description of the function of the subroutine<br>C### should be here.<br>C**** Created by &lt;name&gt; YYYY-MM-DD<br><br> IMPLICIT NONE<br> CHARACTER*(*) ROUTINENAME<br> PARAMETER(ROUTINENAME='SAMPLE')<br> INCLUDE 'cmiss$reference:aaaa00.cmn'<br>! Parameter List<br> INTEGER integer variables in parameter list in alphabetic order<br> REAL*8 real*8 variables in parameter list in alphabetic order<br> COMPLEX complex variables in parameter list in alphabetic order<br> CHARACTER character variables in parameter list in alphabetic order<br> LOGICAL logical variables in parameter list in alphabetic order<br> CHARACTER ERROR*(*)<br>! Local variables<br> INTEGER local integer variables in alphabetic order<br> REAL*8 local real*8 variables in alphabetic order<br> COMPLEX local complex variables in alphabetic order<br> CHARACTER local character variables in alphabetic order<br> LOGICAL local logical variables in alphabetic order<br>! Functions<br> INTEGER integer functions in alphabetic order<br> REAL*8 real*8 functions in alphabetic order<br> CHARACTER character functions in alphabetic order<br> LOGICAL logical functions in alphabetic order<br><br> CALL ENTERS(ROUTINENAME,*9999)<br><br>C Main body of code. NOTE: Variables that are not used should not be<br>C passed or declared as local.<br><br> IF(error condition) THEN<br> CALL FLAG_ERROR(0,'error condition not satisfied')<br> GOTO 9999<br> ENDIF<br><br>C More main body of code. There should be no tabs in the code.<br>C If you are not using emacs then you may need to customize your editor<br>C to prevent it indenting with tabs.<br><br> CALL EXITS(ROUTINENAME)<br> RETURN<br> 9999 CALL ERRORIN(ROUTINENAME)<br> CALL EXITS(ROUTINENAME)<br> RETURN 1<br> END<br></pre>

<p> Functions have a similar form with no ENTERS or EXITS calls: </p><pre> REAL*8 FUNCTION TEST(integer, real*8, complex, character, logical)<br><br>C#### Function: CALC_NUM_SITE<br>C### Type: REAL*8<br>C### Description:<br>C### Returns the length of a piece of string.<br><br> IMPLICIT NONE<br> Variable declarations as for subroutines<br><br> code<br> TEST=RP-DF<br><br> RETURN<br> END<br></pre>

<p> Note: All routines should have a 1 line description at the top of the module. e.g. </p><pre>C### Routine: TEST (fn) solves NP-complete problems in linear time<br>C### Routine: SAMPLE solves NP-complete problems in constant time<br></pre>

<p> The routines in modules should be separated into groups of block data units, then functions, then subroutines, sorted alphabetically within each group.

</p><h1><a name="SECTION00040000000000000000"> Commenting Styles</a> </h1> <pre>C*** For any comment that should stand out<br><br>C??? For any queries<br><br>C!!! For caution remarks.<br>C!!! e.g. suspected bugs, temporary additions, quick hacks (!)<br><br>C PJH 2002-05-29: For major alterations, code deletions<br><br> IF(INLINE_COMMENT) THEN ! Inline comments<br> ENDIF<br><br>C For all other comments<br></pre>

<p> These last two styles are flexible. In general, use '!' for non-intrusive comments and 'C' for more visual comments.

</p><p> When major new variables are introduced the commenting style described in <a name="tex2html1" href="http://www.esc.auckland.ac.nz/Groups/Bioengineering/CMISS/help/programmer/comment-spec.html">documentation comment

format</a>

should be used.

</p><p> All IF statements using codes or flags should be commented. e.g. </p><pre> IF(KTYP26.EQ.1) THEN ! Optimising wrt to material parameters<br>C Statements...<br> ENDIF<br></pre>

<p>

</p><h1><a name="SECTION00050000000000000000"> DO loop format</a> </h1> Use lower case for loop variables. e.g. <pre> DO ng=1,NGT(nb)<br> A(ng)=B(ng)<br> ENDDO !ng<br></pre>

<p> Indicate close of loops with a comment (as above).

</p><p> DO loop counters should be INTEGER and not REAL or DOUBLE PRECISION variables.

</p><p>

</p><h1><a name="SECTION00060000000000000000"> IF statement format</a> </h1> <pre> IF(...) THEN<br> ELSE IF(...) THEN<br> ENDIF !...<br></pre>

<p> Indicate close of conditionals with a comment (as above).

</p><p>

</p><h1><a name="SECTION00070000000000000000"> General</a> </h1> <ul><li>All output should be less than 90 columns. </li><li>All indentation is by 2 spaces, not tabs. If you are using nedit as an editor you will need to edit the preferences so that it does not use tabs for indentation. </li><li>All code lies within 72 columns, and all comments where possible. </li><li>To indicate continuation of the previous line, use `&amp;' as the character

in the 6th column. The code on continued lines should be indented by 2 spaces more than the code on the first line of the statement.
</li><li>All real constants should be explicitly stated as double precision.
Use a small letter `d'. e.g. 0.0d0 not 0. or 0.0
</li><li>All numerical constants or tolerances generally used should be in
symbolic form and defined in a common block, initialized in a block data unit. e.g.

<pre> A=2.0d0*PI<br> IF(DABS(SUM).LT.ZERO_TOL) SUM=0.0d0<br></pre> </li><li>String literals should not span lines. If a long string is required use the concatenation operator to join strings across lines. e.g. <pre> LONG_STRING='If this string was one literal, spread across two '//<br> &amp; 'lines, it would be unclear how many spaces were in the middle.'<br> IF(DABS(SUM).LT.ZERO_TOL) SUM=0.0d0<br></pre> </li><li>Multiple local variables should be like nn1,nn2 not n1n,n2n. </li><li>Initialization of common block variables must NOT be done using DATA statements in procedures or functions; use a block data unit. </li><li>When declaring an array, the dimensions should not be split across more than one line. </li></ul>

<p>

</p><h1><a name="SECTION00080000000000000000"> CM CMGUI Link Code</a> </h1> In order to keep the link between CM and CMGUI up to date, it is necessary to include ``house-keeping'' code inside CM. Currently, this is only implemented for nodes, although in the future it can be expected to be extended to include elements, basis functions, etc. When creating or destroying nodes, it is necessary to call either <tt>NODE_CREATE</tt> or <tt>NODE_DESTROY</tt>. These subroutines take only the node number (i.e. <tt>np</tt>) of the particular node. <pre> CALL NODE_CREATE(np,ERROR,*9999)<br></pre> or <pre> CALL NODE_DESTROY(np,ERROR,*9999)<br></pre>

<p> Whenever you write (or modify) code that modifies nodes (i.e. nodal values or the actual fields that are stored at the node), then it is necessary to add a call to the subroutine <tt>NODE_CHANGE</tt>. This takes the node number <tt>np</tt> to be changed, and whether or not the structure of the node changes. i.e. </p><pre> CALL NODE_CHANGE(np,.TRUE.,ERROR,*9999)<br></pre><name></name>