/[escript]/trunk/finley/src/NodeFile.cpp
ViewVC logotype

Diff of /trunk/finley/src/NodeFile.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 4491 by caltinay, Fri Jun 7 02:23:49 2013 UTC revision 4492 by caltinay, Tue Jul 2 01:44:11 2013 UTC
# Line 22  Line 22 
22    
23  #include "NodeFile.h"  #include "NodeFile.h"
24  #include <escript/Data.h>  #include <escript/Data.h>
25    #include <paso/Coupler.h>
26    
27  #include <limits>  #include <limits>
28  #include <sstream>  #include <sstream>
# Line 54  static void scatterEntries(int n, int* i Line 55  static void scatterEntries(int n, int* i
55    
56  // helper function  // helper function
57  static void gatherEntries(int n, int* index, int min_index, int max_index,  static void gatherEntries(int n, int* index, int min_index, int max_index,
58                            int* Id_out, int* Id_in, int* Tag_out, int* Tag_in,                            int* Id_out, int* Id_in, int* Tag_out, int* Tag_in,
59                            int* globalDegreesOfFreedom_out,                            int* globalDegreesOfFreedom_out,
60                            int* globalDegreesOfFreedom_in,                            int* globalDegreesOfFreedom_in,
61                            int numDim, double* Coordinates_out,                            int numDim, double* Coordinates_out,
62                            double* Coordinates_in)                            double* Coordinates_in)
63  {  {
# Line 88  NodeFile::NodeFile(int nDim, Esys_MPIInf Line 89  NodeFile::NodeFile(int nDim, Esys_MPIInf
89      globalReducedDOFIndex(NULL),      globalReducedDOFIndex(NULL),
90      globalReducedNodesIndex(NULL),      globalReducedNodesIndex(NULL),
91      globalNodesIndex(NULL),      globalNodesIndex(NULL),
     nodesMapping(NULL),  
     reducedNodesMapping(NULL),  
     degreesOfFreedomMapping(NULL),  
     reducedDegreesOfFreedomMapping(NULL),  
92      nodesDistribution(NULL),      nodesDistribution(NULL),
93      reducedNodesDistribution(NULL),      reducedNodesDistribution(NULL),
94      degreesOfFreedomDistribution(NULL),      degreesOfFreedomDistribution(NULL),
# Line 114  NodeFile::~NodeFile() Line 111  NodeFile::~NodeFile()
111  }  }
112    
113  /// allocates the node table within this node file to hold NN nodes.  /// allocates the node table within this node file to hold NN nodes.
114  void NodeFile::allocTable(int NN)  void NodeFile::allocTable(int NN)
115  {  {
116      if (numNodes>0)      if (numNodes>0)
117          freeTable();          freeTable();
# Line 145  void NodeFile::allocTable(int NN) Line 142  void NodeFile::allocTable(int NN)
142          globalNodesIndex[n]=-1;          globalNodesIndex[n]=-1;
143          reducedNodesId[n]=-1;          reducedNodesId[n]=-1;
144          degreesOfFreedomId[n]=-1;          degreesOfFreedomId[n]=-1;
145          reducedDegreesOfFreedomId[n]=-1;          reducedDegreesOfFreedomId[n]=-1;
146      }      }
147  }  }
148    
# Line 163  void NodeFile::freeTable() Line 160  void NodeFile::freeTable()
160      delete[] degreesOfFreedomId;      delete[] degreesOfFreedomId;
161      delete[] reducedDegreesOfFreedomId;      delete[] reducedDegreesOfFreedomId;
162      tagsInUse.clear();      tagsInUse.clear();
163      Finley_NodeMapping_free(nodesMapping);      nodesMapping.clear();
164      nodesMapping=NULL;      reducedNodesMapping.clear();
165      Finley_NodeMapping_free(reducedNodesMapping);      degreesOfFreedomMapping.clear();
166      reducedNodesMapping=NULL;      reducedDegreesOfFreedomMapping.clear();
     Finley_NodeMapping_free(degreesOfFreedomMapping);  
     degreesOfFreedomMapping=NULL;  
     Finley_NodeMapping_free(reducedDegreesOfFreedomMapping);  
     reducedDegreesOfFreedomMapping=NULL;  
167      Paso_Distribution_free(nodesDistribution);      Paso_Distribution_free(nodesDistribution);
168      nodesDistribution=NULL;      nodesDistribution=NULL;
169      Paso_Distribution_free(reducedNodesDistribution);      Paso_Distribution_free(reducedNodesDistribution);
# Line 187  void NodeFile::freeTable() Line 180  void NodeFile::freeTable()
180      numNodes=0;      numNodes=0;
181  }  }
182    
183    void NodeFile::print() const
184    {
185        std::cout << "=== " << numDim << "D-Nodes:\nnumber of nodes=" << numNodes
186            << std::endl;
187        std::cout << "Id,Tag,globalDegreesOfFreedom,degreesOfFreedom,reducedDegreesOfFeedom,node,reducedNode,Coordinates" << std::endl;
188        for (int i=0; i<numNodes; i++) {
189            std::cout << Id[i] << "," << Tag[i] << "," << globalDegreesOfFreedom[i]
190                << "," << degreesOfFreedomMapping.target[i]
191                << "," << reducedDegreesOfFreedomMapping.target[i]
192                << "," << nodesMapping.target[i] << reducedNodesMapping.target[i]
193                << " ";
194            std::cout.precision(15);
195            std::cout.setf(std::ios::scientific, std::ios::floatfield);
196            for (int j=0; j<numDim; j++)
197                std:: cout << Coordinates[INDEX2(j,i,numDim)];
198            std::cout << std::endl;
199        }
200    }
201    
202  /// copies the array newX into this->coordinates  /// copies the array newX into this->coordinates
203  void NodeFile::setCoordinates(const escript::Data& cNewX)  void NodeFile::setCoordinates(const escript::Data& cNewX)
204  {  {
# Line 340  void NodeFile::scatter(int* index, const Line 352  void NodeFile::scatter(int* index, const
352  /// gathers this NodeFile from the NodeFile 'in' using the entries in  /// gathers this NodeFile from the NodeFile 'in' using the entries in
353  /// index[0:out->numNodes-1] which are between min_index and max_index  /// index[0:out->numNodes-1] which are between min_index and max_index
354  /// (exclusive)  /// (exclusive)
355  void NodeFile::gather(int* index, const NodeFile* in)  void NodeFile::gather(int* index, const NodeFile* in)
356  {  {
357      const std::pair<int,int> id_range(in->getGlobalIdRange());      const std::pair<int,int> id_range(in->getGlobalIdRange());
358      gatherEntries(numNodes, index, id_range.first, id_range.second, Id, in->Id,      gatherEntries(numNodes, index, id_range.first, id_range.second, Id, in->Id,
# Line 370  void NodeFile::gather_global(int* index, Line 382  void NodeFile::gather_global(int* index,
382  #pragma omp parallel for  #pragma omp parallel for
383      for (int n=0; n<buffer_len; n++)      for (int n=0; n<buffer_len; n++)
384          Id_buffer[n]=undefined_node;          Id_buffer[n]=undefined_node;
385        
386      // fill the buffer by sending portions around in a circle      // fill the buffer by sending portions around in a circle
387  #ifdef ESYS_MPI  #ifdef ESYS_MPI
388      MPI_Status status;      MPI_Status status;
# Line 475  void NodeFile::assignMPIRankToDOFs(Esys_ Line 487  void NodeFile::assignMPIRankToDOFs(Esys_
487              }              }
488          }          }
489      }      }
490  }  }
491    
492  int NodeFile::prepareLabeling(int* mask, std::vector<int>& buffer,  int NodeFile::prepareLabeling(int* mask, std::vector<int>& buffer,
493                                std::vector<int>& distribution, bool useNodes)                                std::vector<int>& distribution, bool useNodes)
# Line 600  int NodeFile::createDenseDOFLabeling() Line 612  int NodeFile::createDenseDOFLabeling()
612  }  }
613    
614  int NodeFile::createDenseNodeLabeling(int* node_distribution,  int NodeFile::createDenseNodeLabeling(int* node_distribution,
615                                        const int* dof_distribution)                                        const int* dof_distribution)
616  {  {
617      const int UNSET_ID=-1, SET_ID=1;      const int UNSET_ID=-1, SET_ID=1;
618      const int myFirstDOF=dof_distribution[MPIInfo->rank];      const int myFirstDOF=dof_distribution[MPIInfo->rank];
# Line 713  int NodeFile::createDenseNodeLabeling(in Line 725  int NodeFile::createDenseNodeLabeling(in
725      return globalNumNodes;      return globalNumNodes;
726  }  }
727    
728  int NodeFile::createDenseReducedLabeling(int* reducedMask, bool useNodes)  int NodeFile::createDenseReducedLabeling(int* reducedMask, bool useNodes)
729  {  {
730      std::vector<int> buffer;      std::vector<int> buffer;
731      std::vector<int> distribution;      std::vector<int> distribution;
# Line 782  int NodeFile::createDenseReducedLabeling Line 794  int NodeFile::createDenseReducedLabeling
794      return new_numGlobalReduced;      return new_numGlobalReduced;
795  }  }
796    
797    void NodeFile::createDOFMappingAndCoupling(bool use_reduced_elements)
798    {
799        Paso_Distribution* dof_distribution;
800        const int* globalDOFIndex;
801        if (use_reduced_elements) {
802            dof_distribution=reducedDegreesOfFreedomDistribution;
803            globalDOFIndex=globalReducedDOFIndex;
804        } else {
805            dof_distribution=degreesOfFreedomDistribution;
806            globalDOFIndex=globalDegreesOfFreedom;
807        }
808        const int myFirstDOF=Paso_Distribution_getFirstComponent(dof_distribution);
809        const int myLastDOF=Paso_Distribution_getLastComponent(dof_distribution);
810        const int mpiSize=MPIInfo->size;
811        const int myRank=MPIInfo->rank;
812    
813        int min_DOF, max_DOF;
814        std::pair<int,int> DOF_range(util::getFlaggedMinMaxInt(
815                                                numNodes, globalDOFIndex, -1));
816    
817        if (DOF_range.second < DOF_range.first) {
818            min_DOF=myFirstDOF;
819            max_DOF=myLastDOF-1;
820        } else {
821            min_DOF=DOF_range.first;
822            max_DOF=DOF_range.second;
823        }
824    
825        int p_min=mpiSize;
826        int p_max=-1;
827        if (max_DOF >= min_DOF) {
828            for (int p=0; p<mpiSize; ++p) {
829                if (dof_distribution->first_component[p]<=min_DOF) p_min=p;
830                if (dof_distribution->first_component[p]<=max_DOF) p_max=p;
831            }
832        }
833    
834        if (!((min_DOF<=myFirstDOF) && (myLastDOF-1<=max_DOF))) {
835            Finley_setError(SYSTEM_ERROR, "Local elements do not span local degrees of freedom.");
836            return;
837        }
838        const int UNUSED = -1;
839        const int len_loc_dof=max_DOF-min_DOF+1;
840        std::vector<int> shared(numNodes*(p_max-p_min+1));
841        std::vector<int> offsetInShared(mpiSize+1);
842        std::vector<int> locDOFMask(len_loc_dof, UNUSED);
843    
844    #pragma omp parallel
845        {
846    #pragma omp for
847            for (int i=0;i<numNodes;++i) {
848                const int k=globalDOFIndex[i];
849                if (k > -1) {
850    #ifdef BOUNDS_CHECK
851                    if ((k-min_DOF)>=len_loc_dof) {
852                        printf("BOUNDS_CHECK %s %d i=%d k=%d min_DOF=%d\n", __FILE__, __LINE__, i, k, min_DOF);
853                        exit(1);
854                    }
855    #endif
856                    locDOFMask[k-min_DOF]=UNUSED-1;
857                }
858           }
859    #ifdef BOUNDS_CHECK
860           if (myLastDOF-min_DOF > len_loc_dof) {
861               printf("BOUNDS_CHECK %s %d\n", __FILE__, __LINE__);
862               exit(1);
863           }
864    #endif
865    #pragma omp for
866           for (int i=myFirstDOF-min_DOF; i<myLastDOF-min_DOF; ++i) {
867                locDOFMask[i]=i-myFirstDOF+min_DOF;
868            }
869        }
870    
871        std::vector<int> wanted_DOFs(numNodes);
872        std::vector<int> rcv_len(mpiSize);
873        std::vector<int> snd_len(mpiSize);
874        std::vector<int> neighbor(mpiSize);
875        int numNeighbors=0;
876        int n=0;
877        int lastn=n;
878        for (int p=p_min; p<=p_max; ++p) {
879            if (p != myRank) {
880                const int firstDOF=std::max(min_DOF, dof_distribution->first_component[p]);
881                const int lastDOF=std::min(max_DOF+1, dof_distribution->first_component[p+1]);
882    #ifdef BOUNDS_CHECK
883                if (firstDOF-min_DOF<0 || lastDOF-min_DOF>len_loc_dof) {
884                    printf("BOUNDS_CHECK %s %d p=%d\n", __FILE__, __LINE__, p);
885                    exit(1);
886                }
887    #endif
888                for (int i=firstDOF-min_DOF; i<lastDOF-min_DOF; ++i) {
889                    if (locDOFMask[i] == UNUSED-1) {
890                       locDOFMask[i]=myLastDOF-myFirstDOF+n;
891                       wanted_DOFs[n]=i+min_DOF;
892                       ++n;
893                    }
894                }
895                if (n > lastn) {
896                    rcv_len[p]=n-lastn;
897    #ifdef BOUNDS_CHECK
898                    if (numNeighbors >= mpiSize+1) {
899                        printf("BOUNDS_CHECK %s %d p=%d numNeighbors=%d n=%d\n", __FILE__, __LINE__, p, numNeighbors, n);
900                        exit(1);
901                    }
902    #endif
903                    neighbor[numNeighbors]=p;
904                    offsetInShared[numNeighbors]=lastn;
905                    numNeighbors++;
906                    lastn=n;
907                }
908            } // if p!=myRank
909        } // for p
910    
911    #ifdef BOUNDS_CHECK
912        if (numNeighbors >= mpiSize+1) {
913            printf("BOUNDS_CHECK %s %d numNeighbors=%d\n", __FILE__, __LINE__, numNeighbors);
914            exit(1);
915        }
916    #endif
917        offsetInShared[numNeighbors]=lastn;
918    
919        // assign new DOF labels to nodes
920        std::vector<int> nodeMask(numNodes, UNUSED);
921    #pragma omp parallel for
922        for (int i=0; i<numNodes; ++i) {
923            const int k=globalDOFIndex[i];
924            if (k > -1)
925                nodeMask[i]=locDOFMask[k-min_DOF];
926        }
927    
928        // now we can set the mapping from nodes to local DOFs
929        if (use_reduced_elements) {
930            reducedDegreesOfFreedomMapping.assign(nodeMask, UNUSED);
931        } else {
932            degreesOfFreedomMapping.assign(nodeMask, UNUSED);
933        }
934    
935        // define how to get DOF values for controlled but other processors
936    #ifdef BOUNDS_CHECK
937        if (offsetInShared[numNeighbours] >= numNodes*(p_max-p_min+1)) {
938            printf("BOUNDS_CHECK %s %d\n", __FILE__, __LINE__);
939            exit(1);
940        }
941    #endif
942    #pragma omp parallel for
943        for (int i=0; i<offsetInShared[numNeighbors]; ++i)
944            shared[i]=myLastDOF-myFirstDOF+i;
945    
946        Paso_SharedComponents *rcv_shcomp=Paso_SharedComponents_alloc(
947                myLastDOF-myFirstDOF, numNeighbors, &neighbor[0], &shared[0],
948                &offsetInShared[0], 1, 0, MPIInfo);
949    
950        /////////////////////////////////
951        //   now we build the sender   //
952        /////////////////////////////////
953    #ifdef ESYS_MPI
954        std::vector<MPI_Request> mpi_requests(mpiSize*2);
955        std::vector<MPI_Status> mpi_stati(mpiSize*2);
956        MPI_Alltoall(&rcv_len[0], 1, MPI_INT, &snd_len[0], 1, MPI_INT, MPIInfo->comm);
957        int count=0;
958    #else
959        snd_len[0]=rcv_len[0];
960    #endif
961    
962        for (int p=0; p<rcv_shcomp->numNeighbors; p++) {
963    #ifdef ESYS_MPI
964            MPI_Isend(&(wanted_DOFs[rcv_shcomp->offsetInShared[p]]),
965                    rcv_shcomp->offsetInShared[p+1]-rcv_shcomp->offsetInShared[p],
966                    MPI_INT, rcv_shcomp->neighbor[p],
967                    MPIInfo->msg_tag_counter+myRank, MPIInfo->comm,
968                    &mpi_requests[count]);
969            count++;
970    #endif
971        }
972        n=0;
973        numNeighbors=0;
974        for (int p=0; p<mpiSize; p++) {
975            if (snd_len[p] > 0) {
976    #ifdef ESYS_MPI
977                MPI_Irecv(&shared[n], snd_len[p], MPI_INT, p,
978                        MPIInfo->msg_tag_counter+p, MPIInfo->comm,
979                        &mpi_requests[count]);
980                count++;
981    #endif
982                neighbor[numNeighbors]=p;
983                offsetInShared[numNeighbors]=n;
984                numNeighbors++;
985                n+=snd_len[p];
986            }
987        }
988        MPIInfo->msg_tag_counter+=MPIInfo->size;
989        offsetInShared[numNeighbors]=n;
990    #ifdef ESYS_MPI
991        MPI_Waitall(count, &mpi_requests[0], &mpi_stati[0]);
992    #endif
993        // map global ids to local id's
994    #pragma omp parallel for
995        for (int i=0; i<offsetInShared[numNeighbors]; ++i) {
996            shared[i]=locDOFMask[shared[i]-min_DOF];
997        }
998    
999        Paso_SharedComponents* snd_shcomp=Paso_SharedComponents_alloc(
1000                myLastDOF-myFirstDOF, numNeighbors, &neighbor[0], &shared[0],
1001                &offsetInShared[0], 1, 0, MPIInfo);
1002    
1003        if (Finley_noError()) {
1004            if (use_reduced_elements) {
1005                reducedDegreesOfFreedomConnector=Paso_Connector_alloc(snd_shcomp, rcv_shcomp);
1006            } else {
1007                degreesOfFreedomConnector=Paso_Connector_alloc(snd_shcomp, rcv_shcomp);
1008            }
1009        }
1010    
1011        Paso_SharedComponents_free(rcv_shcomp);
1012        Paso_SharedComponents_free(snd_shcomp);
1013    }
1014    
1015    void NodeFile::createNodeMappings(int numReducedNodes,
1016                                      const std::vector<int>& indexReducedNodes,
1017                                      const int* dofDist, const int* nodeDist)
1018    {
1019        const int mpiSize=MPIInfo->size;
1020        const int myRank=MPIInfo->rank;
1021    
1022        const int myFirstDOF=dofDist[myRank];
1023        const int myLastDOF=dofDist[myRank+1];
1024        const int myNumDOF=myLastDOF-myFirstDOF;
1025    
1026        const int myFirstNode=nodeDist[myRank];
1027        const int myLastNode=nodeDist[myRank+1];
1028        const int myNumNodes=myLastNode-myFirstNode;
1029    
1030        std::vector<int> maskMyReducedDOF(myNumDOF, -1);
1031        std::vector<int> maskMyReducedNodes(myNumNodes, -1);
1032    
1033        // mark the nodes used by the reduced mesh
1034    #pragma omp parallel for
1035        for (int i=0; i<numReducedNodes; ++i) {
1036            int k=globalNodesIndex[indexReducedNodes[i]];
1037            if (k>=myFirstNode && myLastNode>k)
1038                maskMyReducedNodes[k-myFirstNode]=i;
1039            k=globalDegreesOfFreedom[indexReducedNodes[i]];
1040            if (k>=myFirstDOF && myLastDOF>k) {
1041                maskMyReducedDOF[k-myFirstDOF]=i;
1042            }
1043        }
1044        std::vector<int> indexMyReducedDOF(myNumDOF);
1045        std::vector<int> indexMyReducedNodes(myNumNodes);
1046        int myNumReducedDOF=util::packMask(myNumDOF, &maskMyReducedDOF[0], &indexMyReducedDOF[0]);
1047        int myNumReducedNodes=util::packMask(myNumNodes, &maskMyReducedNodes[0], &indexMyReducedNodes[0]);
1048    
1049        std::vector<int> rdofDist(mpiSize+1);
1050        std::vector<int> rnodeDist(mpiSize+1);
1051    #ifdef ESYS_MPI
1052        MPI_Allgather(&myNumReducedNodes, 1, MPI_INT, &rnodeDist[0], 1, MPI_INT, MPIInfo->comm);
1053        MPI_Allgather(&myNumReducedDOF, 1, MPI_INT, &rdofDist[0], 1, MPI_INT, MPIInfo->comm);
1054    #else
1055        rnodeDist[0]=myNumReducedNodes;
1056        rdofDist[0]=myNumReducedDOF;
1057    #endif
1058        int globalNumReducedNodes=0;
1059        int globalNumReducedDOF=0;
1060        for (int i=0; i<mpiSize;++i) {
1061            int k=rnodeDist[i];
1062            rnodeDist[i]=globalNumReducedNodes;
1063            globalNumReducedNodes+=k;
1064    
1065            k=rdofDist[i];
1066            rdofDist[i]=globalNumReducedDOF;
1067            globalNumReducedDOF+=k;
1068        }
1069        rnodeDist[mpiSize]=globalNumReducedNodes;
1070        rdofDist[mpiSize]=globalNumReducedDOF;
1071    
1072        // ==== distribution of Nodes ===============================
1073        nodesDistribution=Paso_Distribution_alloc(MPIInfo, nodeDist, 1, 0);
1074        // ==== distribution of DOFs ================================
1075        degreesOfFreedomDistribution=Paso_Distribution_alloc(MPIInfo, &dofDist[0], 1,0);
1076        // ==== distribution of reduced Nodes =======================
1077        reducedNodesDistribution=Paso_Distribution_alloc(MPIInfo, &rnodeDist[0], 1, 0);
1078        // ==== distribution of reduced DOF =========================
1079        reducedDegreesOfFreedomDistribution=Paso_Distribution_alloc(MPIInfo, &rdofDist[0], 1, 0);
1080    
1081        std::vector<int> nodeMask(numNodes);
1082    
1083        if (Finley_noError()) {
1084            const int UNUSED = -1;
1085            // ==== nodes mapping which is a dummy structure ========
1086    #pragma omp parallel for
1087            for (int i=0; i<numNodes; ++i)
1088                nodeMask[i]=i;
1089            nodesMapping.assign(nodeMask, UNUSED);
1090    
1091            // ==== mapping between nodes and reduced nodes ==========
1092    #pragma omp parallel for
1093            for (int i=0; i<numNodes; ++i)
1094                nodeMask[i]=UNUSED;
1095    #pragma omp parallel for
1096            for (int i=0; i<numReducedNodes; ++i)
1097                nodeMask[indexReducedNodes[i]]=i;
1098            reducedNodesMapping.assign(nodeMask, UNUSED);
1099        }
1100        // ==== mapping between nodes and DOFs + DOF connector
1101        if (Finley_noError())
1102            createDOFMappingAndCoupling(false);
1103        // ==== mapping between nodes and reduced DOFs + reduced DOF connector
1104        if (Finley_noError())
1105            createDOFMappingAndCoupling(true);
1106    
1107        // get the Ids for DOFs and reduced nodes
1108        if (Finley_noError()) {
1109    #pragma omp parallel private(i)
1110            {
1111    #pragma omp for
1112             for (int i=0; i<reducedNodesMapping.getNumTargets(); ++i)
1113                 reducedNodesId[i]=Id[reducedNodesMapping.map[i]];
1114    #pragma omp for
1115             for (int i=0; i<degreesOfFreedomMapping.getNumTargets(); ++i)
1116                 degreesOfFreedomId[i]=Id[degreesOfFreedomMapping.map[i]];
1117    #pragma omp for
1118             for (int i=0; i<reducedDegreesOfFreedomMapping.getNumTargets(); ++i)
1119                 reducedDegreesOfFreedomId[i]=Id[reducedDegreesOfFreedomMapping.map[i]];
1120            }
1121        } else {
1122            Paso_Distribution_free(nodesDistribution);
1123            Paso_Distribution_free(reducedNodesDistribution);
1124            Paso_Distribution_free(degreesOfFreedomDistribution);
1125            Paso_Distribution_free(reducedDegreesOfFreedomDistribution);
1126            Paso_Connector_free(degreesOfFreedomConnector);
1127            Paso_Connector_free(reducedDegreesOfFreedomConnector);
1128            nodesDistribution=NULL;
1129            reducedNodesDistribution=NULL;
1130            degreesOfFreedomDistribution=NULL;
1131            reducedDegreesOfFreedomDistribution=NULL;
1132            degreesOfFreedomConnector=NULL;
1133            reducedDegreesOfFreedomConnector=NULL;
1134        }
1135    }
1136    
1137  } // namespace finley  } // namespace finley
1138    

Legend:
Removed from v.4491  
changed lines
  Added in v.4492

  ViewVC Help
Powered by ViewVC 1.1.26