Domain Logic ============ .. contents:: :local: ------ Some general developing guide is given here. General Rules ------------- - Do **not** “invent” new functions. For well-defined things, check if it is already realized in STL, Boost, Eigen, in computational chemical communities, or in this project. If you are not sure, consult the project leader. - Always design a **low-coupling** module, class, and function. It should has the least dependence on other code. General Libraries ----------------- STL +++ - STL provides a lot of excellent containers. In this project, ``vector``, ``map``, and ``set`` has been extensively used. For **performance-nonsensitive** code, they are highly flexible and efficient and are strongly recommended. Developer does not have to bother with memory issues. - Remember to use ``reserve`` for efficient implementaion. - For ``vector``, its visit can be done using the traditional ``for (int i = 0; i < size; ++i)``, or ``iterator`` or ``const_iterator`` if read-only. Developer can choose a suitable way according to the context. - ``vector`` can be used as an ordinary array by ``data()``. - For ``map`` or ``set``, their visit must be done with ``iterator`` or ``const_iterator`` if read-only. - Do **not** use things like ``for (auto x : vectorX)``. Boost +++++ - Boost provides a lot of general functions for C++ and developer should use **approved libraries** from the Boost library collection. - In this project, all parsing works are done by ``spirit`` from Boost. - In this project, all graph theory operations are done by ``BGL`` from Boost. - Boost also provides realization of a lot of special functions like Bessel functions. kiseki ------ Error +++++ - When there is an error that the program must terminate, please use the macro ``ErrorTermination`` in ``src/system/RunStatus.h`` to gracefully stop. .. code-block:: cpp :caption: src/system/CodeInfo.h if ((words.size() == 2 || words.size() == 3) && (Parser::ParseInteger(words[1], K))) { // ... } else { ErrorTermination("Basis set format at \"%s\" is incorrect. It should be like \"P(angular momentum) " "5(contraction degree) 1.00(real number)\" or \"0 10 1.00\".", tstr.c_str()); } - The error information should be given as detailed as possible. Print +++++ - When you want to print something on ``stdout``, **always** use ``mprintf`` or ``lmprintf`` in ``src/system/lmfprintf.h``. This guarantees the consistent behaviour of the program in single and multiple-node version. .. code-block:: cpp :caption: src/system/CodeInfo.h mprintf("Platform: %s\n", compiling_info.platform.c_str()); mprintf("Compiled by: %s@%s\n", compiling_info.user.c_str(), compiling_info.machine.c_str()); mprintf("Compiling date: %s\n", compiling_info.time.c_str()); mprintf("C++ compiler: %s\n", compiling_info.compiler.c_str()); mprintf("C++ options: %s\n", compiling_info.compiling_flags.c_str()); mprintf("Libraries: %s\n", compiling_info.libs.c_str()); - ``lmprintf`` is short for logic mprintf. This is use for printing level control. Sometimes a function may be called be many higher level functions, which may have different printing requirement. For example, when SCF energy is called by an energy calculation, it will print long output; but when it is called by a geometry optimization function, only part of the output is needed. In this case, a logic flag can be used to control the behavior easily. .. code-block:: cpp :caption: src/scf/SelfConsistentField.h // When print_details is set to false, these words will not be output. lmprintf(print_details, " ---- Self Consistent Field Gradient Begun -----------------\n"); lmprintf(print_details, " ===========================================================\n"); lmprintf(print_details, "\n"); lmprintf(print_details, " ---- Self Consistent Field Gradient Done ------------------\n"); lmprintf(print_details, "\n"); - Things like ``printf`` or ``cout`` can only be used for debug and should not appear in released codes. Parse +++++ - The class in ``src/system/Parser.h`` gives a lot of functions for parsing strings. +-------------------------------+---------------------------------------------------------------------------------------+ | Function | Example | +===============================+=======================================================================================+ | ``Parser::ParseInteger`` | Transform ``"-34"`` to ``-34``. | +-------------------------------+---------------------------------------------------------------------------------------+ | ``Parser::ParseRealNumber`` | Transform ``"31.4"`` or ``"3.14E+01"`` to ``31.4``. | +-------------------------------+---------------------------------------------------------------------------------------+ | ``Parser::ParseNumberRange`` | Transform ``"3-9"`` to ``{3,9}``, and ``"7"`` to ``{7,7}`` | +-------------------------------+---------------------------------------------------------------------------------------+ | ``Parser::SplitSentence`` | Transform ``"filename a.inp b.inp"`` to a vector: ``{"filename", "a.inp", "b.inp"}``. | +-------------------------------+---------------------------------------------------------------------------------------+ | ``Parser::ToUpperCase`` | Transform ``"aBcD eFgH"`` to ``"ABCD EFGH"``. | +-------------------------------+---------------------------------------------------------------------------------------+ | ``Parser::ToLowerCase`` | Transform ``"aBcD eFgH"`` to ``"abcd efgh"``. | +-------------------------------+---------------------------------------------------------------------------------------+ - One can refer to ``src/scf/SelfConsistentField_SCFArgs.cpp`` to see how the program is parsing configurations from an input file. Running Information +++++++++++++++++++ - To access the running information of the program, one should refer to ``src/system/RunStatus.h``. +-------------------------------+---------------------------------------------------------------------------------------+ | Function | Description | +===============================+=======================================================================================+ | ``RunStatus::GetJobName`` | If the input file is ``water.inp``, then this returns ``water``. | +-------------------------------+---------------------------------------------------------------------------------------+ | ``RunStatus::GetTime`` | Get the current time. | +-------------------------------+---------------------------------------------------------------------------------------+ | ``RunStatus::GetDuration`` | Get the difference between two time objects obtained by ``RunStatus::GetTime``. | +-------------------------------+---------------------------------------------------------------------------------------+ | ``RunStatus::GetScratchPath`` | Get the scratch path provided by user through ``-s`` argument. | +-------------------------------+---------------------------------------------------------------------------------------+ | ``RunStatus::GetMemorySize`` | Get the maximum memory size provided by user through ``-m`` argument. | +-------------------------------+---------------------------------------------------------------------------------------+ | ``RunStatus::GetDiskSize`` | Get the maximum disk size provided by user through ``-d`` argument. | +-------------------------------+---------------------------------------------------------------------------------------+ OpenMP and MPI Parallelization ++++++++++++++++++++++++++++++ - Read ``src/system/ComputationalResource.h`` carefully. It provides all functions needed to manipulate parallelization. - Do not include something like ````, ```` or use ``omp_get_num_threads``, ``MPI_Comm_rank`` explicitly in your code. It has been wrapped in ``src/system/ComputationalResource.h`` so a consistent behavior can be obtained for OpenMP and MPI version of the program. So, please use ``ComputationalResource::GetOpenMPRank();`` to get the current OpenMP ID. +----------------------------------------------+------------------------------------------------------------------------+ | Function | Description | +==============================================+========================================================================+ | ``ComputationalResource::GetOpenMPRank`` | Get the OpenMP thread ID of the current MPI process. | +----------------------------------------------+------------------------------------------------------------------------+ | ``ComputationalResource::GetMPIRank`` | Get the process ID of the current MPI process. | +----------------------------------------------+------------------------------------------------------------------------+ | ``ComputationalResource::GetFreeMemorySize`` | Get the free memory size of current node in byte. | +----------------------------------------------+------------------------------------------------------------------------+ | ``ComputationalResource::GetFreeDiskSize`` | Get the free disk size in byte for the given path. | +----------------------------------------------+------------------------------------------------------------------------+ - For MPI call, please use the macro ``MPI_Check`` in ``src/system/ComputationalResource.h``, like ``MPI_Check(MPI_AllReduce(...))``. Input Design ------------ - TODO Quantum Chemistry Coding ------------------------ - TODO Molecular Mechanics Coding -------------------------- - TODO