def calc_force(self, dry_run=False):
        """
        calculate force (energy gradient)

        absolute: force -> gradient
        """
        if self.is_finished_force:
            logger.info("force has been calced.")
            return

        if self.is_finished_scf != True:
            self.calc_sp(dry_run)

        self.cd_work_dir("calc force")

        self._setup_pdf()
        self.pdfparam.step_control = "force"
        self.save()

        pdfsim = pdf.PdfSim()
        # for frg_name, frg in self.fragments():
        #     frg.set_basisset(self.pdfparam)
        # self.pdfparam.molecule = self.frame_molecule
        #
        # # num_of_electrons
        # num_of_electrons = self.pdfparam.num_of_electrons # calc from the molecule data
        # logger.info('the number of electrons = {}'.format(num_of_electrons))
        # if self.charge != 0:
        #     logger.info('specify the charge => {}'.format(self.charge))
        #     num_of_electrons -= self.charge # 電子(-)数と電荷(+)の正負が逆なことに注意
        #     self.pdfparam.num_of_electrons = num_of_electrons
        #     logger.info('update the number of electrons => {}'.format(self.pdfparam.num_of_electrons))
        pdfsim.sp(
            self.pdfparam,
            workdir=self.work_dir,
            db_path=self.db_path,
            dry_run=dry_run,
            cmd_archive=self._cmds["archive"],
        )

        self._cache.pop("pdfparam")
        self.is_finished_force = True
        self.save()

        self.restore_cwd()