| 1838 | ******************************************************************/ |
| 1839 | |
| 1840 | static int CVnlsFunctional(CVodeMem cv_mem) |
| 1841 | { |
| 1842 | int m; |
| 1843 | real del, delp, dcon; |
| 1844 | |
| 1845 | /* Initialize counter and evaluate f at predicted y */ |
| 1846 | |
| 1847 | crate = ONE; |
| 1848 | m = 0; |
| 1849 | f(N, tn, zn[0], tempv, f_data); |
| 1850 | nfe++; |
| 1851 | N_VConst(ZERO, acor); |
| 1852 | |
| 1853 | /* Loop until convergence; accumulate corrections in acor */ |
| 1854 | |
| 1855 | loop { |
| 1856 | /* Correct y directly from the last f value */ |
| 1857 | N_VLinearSum(h, tempv, -ONE, zn[1], tempv); |
| 1858 | N_VScale(rl1, tempv, tempv); |
| 1859 | N_VLinearSum(ONE, zn[0], ONE, tempv, y); |
| 1860 | /* Get WRMS norm of current correction to use in convergence test */ |
| 1861 | N_VLinearSum(ONE, tempv, -ONE, acor, acor); |
| 1862 | del = N_VWrmsNorm(acor, ewt); |
| 1863 | N_VScale(ONE, tempv, acor); |
| 1864 | |
| 1865 | /* Test for convergence. If m > 0, an estimate of the convergence |
| 1866 | rate constant is stored in crate, and used in the test. */ |
| 1867 | if (m > 0) crate = MAX(CRDOWN * crate, del / delp); |
| 1868 | dcon = del * MIN(ONE, crate) / tq[4]; |
| 1869 | if (dcon <= ONE) { |
| 1870 | acnrm = (m == 0) ? del : N_VWrmsNorm(acor, ewt); |
| 1871 | return(SOLVED); /* Convergence achieved */ |
| 1872 | } |
| 1873 | |
| 1874 | /* Stop at maxcor iterations or if iter. seems to be diverging */ |
| 1875 | m++; |
| 1876 | if ((m==maxcor) || ((m >= 2) && (del > RDIV * delp))) |
| 1877 | return(CONV_FAIL); |
| 1878 | /* Save norm of correction, evaluate f, and loop again */ |
| 1879 | delp = del; |
| 1880 | f(N, tn, y, tempv, f_data); |
| 1881 | nfe++; |
| 1882 | } |
| 1883 | } |
| 1884 | |
| 1885 | /*********************** CVnlsNewton ********************************** |
no test coverage detected